@abi-software/map-side-bar 2.14.8-demo.4 → 2.14.8-demo.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/dist/map-side-bar.js +6136 -5965
- package/dist/map-side-bar.umd.cjs +43 -40
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/App.vue +1 -0
- package/src/components/ConnectivityInfo.vue +198 -1
- package/src/components/ContributorItem.vue +108 -0
- package/src/components.d.ts +1 -0
package/package.json
CHANGED
package/src/App.vue
CHANGED
|
@@ -137,6 +137,7 @@ export default {
|
|
|
137
137
|
ROOT_URL: import.meta.env.VITE_APP_ROOT_URL,
|
|
138
138
|
FLATMAPAPI_LOCATION: import.meta.env.VITE_FLATMAPAPI_LOCATION,
|
|
139
139
|
CELL_CARDS_API: import.meta.env.VITE_APP_CELL_CARDS_API,
|
|
140
|
+
CORS_PROXY_API: import.meta.env.VITE_CORS_PROXY_API,
|
|
140
141
|
},
|
|
141
142
|
connectivityEntry: [],
|
|
142
143
|
createData: {
|
|
@@ -303,6 +303,22 @@
|
|
|
303
303
|
></div>
|
|
304
304
|
</div>
|
|
305
305
|
</div>
|
|
306
|
+
|
|
307
|
+
<div class="content-container" v-if="expertConsultants.length">
|
|
308
|
+
<div class="block attribute-title-container">
|
|
309
|
+
<span class="attribute-title">Expert Consultants</span>
|
|
310
|
+
</div>
|
|
311
|
+
<ul class="block consultant-block">
|
|
312
|
+
<li v-for="consultant in expertConsultants" :key="consultant.url">
|
|
313
|
+
<template v-if="consultant.name">
|
|
314
|
+
<contributor-item :contributor="consultant" />
|
|
315
|
+
</template>
|
|
316
|
+
<div class="consultant-loading" v-else>
|
|
317
|
+
<span>Loading {{ consultant.url }}</span>
|
|
318
|
+
</div>
|
|
319
|
+
</li>
|
|
320
|
+
</ul>
|
|
321
|
+
</div>
|
|
306
322
|
</div>
|
|
307
323
|
</template>
|
|
308
324
|
|
|
@@ -320,7 +336,7 @@ import {
|
|
|
320
336
|
ElContainer as Container,
|
|
321
337
|
ElIcon as Icon,
|
|
322
338
|
} from 'element-plus'
|
|
323
|
-
|
|
339
|
+
import ContributorItem from './ContributorItem.vue'
|
|
324
340
|
import EventBus from './EventBus.js'
|
|
325
341
|
import {
|
|
326
342
|
CopyToClipboard,
|
|
@@ -354,6 +370,7 @@ export default {
|
|
|
354
370
|
ConnectivityGraph,
|
|
355
371
|
ConnectivityList,
|
|
356
372
|
ConnectivityReconciliationList,
|
|
373
|
+
ContributorItem,
|
|
357
374
|
},
|
|
358
375
|
props: {
|
|
359
376
|
connectivityEntry: {
|
|
@@ -397,6 +414,8 @@ export default {
|
|
|
397
414
|
connectivityFromMap: null,
|
|
398
415
|
isTitleExpanded: false,
|
|
399
416
|
showTitleToggle: false,
|
|
417
|
+
storedReferences: null,
|
|
418
|
+
expertConsultants: [],
|
|
400
419
|
};
|
|
401
420
|
},
|
|
402
421
|
computed: {
|
|
@@ -468,8 +487,17 @@ export default {
|
|
|
468
487
|
flatmapApi: function () {
|
|
469
488
|
return this.envVars.FLATMAPAPI_LOCATION;
|
|
470
489
|
},
|
|
490
|
+
expertConsultantURLs: function () {
|
|
491
|
+
return this.entryData['expert-consultants'] || [];
|
|
492
|
+
},
|
|
471
493
|
},
|
|
472
494
|
watch: {
|
|
495
|
+
entryData: {
|
|
496
|
+
deep: true,
|
|
497
|
+
handler: function () {
|
|
498
|
+
this.fetchExpertConsultants();
|
|
499
|
+
},
|
|
500
|
+
},
|
|
473
501
|
entry: {
|
|
474
502
|
deep: true,
|
|
475
503
|
immediate: true,
|
|
@@ -613,6 +641,7 @@ export default {
|
|
|
613
641
|
this.$emit('show-reference-connectivities', refSource);
|
|
614
642
|
},
|
|
615
643
|
onReferencesLoaded: function (references) {
|
|
644
|
+
this.storedReferences = references;
|
|
616
645
|
this.updatedCopyContent = this.getUpdateCopyContent(references);
|
|
617
646
|
},
|
|
618
647
|
getUpdateCopyContent: function (references) {
|
|
@@ -794,6 +823,47 @@ export default {
|
|
|
794
823
|
contentArray.push(contentString);
|
|
795
824
|
}
|
|
796
825
|
|
|
826
|
+
// Expert Consultants
|
|
827
|
+
if (this.expertConsultants?.length) {
|
|
828
|
+
let contentString = `<div><strong>Expert Consultants</strong></div>`;
|
|
829
|
+
contentString += '\n';
|
|
830
|
+
const contentList = this.expertConsultants
|
|
831
|
+
.filter((consultant) => consultant.name)
|
|
832
|
+
.map((consultant) => {
|
|
833
|
+
const fields = [`<div><strong>${consultant.name}</strong></div>`];
|
|
834
|
+
|
|
835
|
+
if (consultant.orcidId) {
|
|
836
|
+
fields.push(`<div>`)
|
|
837
|
+
fields.push(`<strong>ORCID iD</strong>: <span>${consultant.orcidId}</span>`)
|
|
838
|
+
fields.push(`(<a href="${consultant.url}" target="_blank" rel="noopener noreferrer">${consultant.url}</a>)`)
|
|
839
|
+
fields.push(`</div>`);
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
const rrid = consultant.url.indexOf('RRID:') > -1
|
|
843
|
+
? 'RRID:' + consultant.url.split('RRID:')[1]
|
|
844
|
+
: '';
|
|
845
|
+
if (rrid) {
|
|
846
|
+
fields.push(`<div>`)
|
|
847
|
+
fields.push(`<strong>RRID</strong>: <span>${rrid}</span>`)
|
|
848
|
+
fields.push(`(<a href="${consultant.url}" target="_blank" rel="noopener noreferrer">${consultant.url}</a>)`)
|
|
849
|
+
fields.push(`</div>`);
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
if (consultant.organization) {
|
|
853
|
+
fields.push(`<div><strong>Organization</strong>: ${consultant.organization}</div>`);
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
if (consultant.role) {
|
|
857
|
+
fields.push(`<div><strong>Title</strong>: ${consultant.role}</div>`);
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
return `<li>${fields.join('\n')}</li>`;
|
|
861
|
+
})
|
|
862
|
+
.join('\n');
|
|
863
|
+
contentString += `<ul>${contentList}</ul>`;
|
|
864
|
+
contentArray.push(contentString);
|
|
865
|
+
}
|
|
866
|
+
|
|
797
867
|
// Alert (Notes)
|
|
798
868
|
if (this.entry.featuresAlert?.length) {
|
|
799
869
|
const alertContent = this.entry.featuresAlert
|
|
@@ -825,6 +895,70 @@ export default {
|
|
|
825
895
|
});
|
|
826
896
|
return data
|
|
827
897
|
},
|
|
898
|
+
fetchExpertConsultants: async function () {
|
|
899
|
+
this.expertConsultants = this.expertConsultantURLs.map(url => ({ name: '', url }));
|
|
900
|
+
|
|
901
|
+
for (const url of this.expertConsultantURLs) {
|
|
902
|
+
const isScicrunchURL = url.startsWith('https://scicrunch.org');
|
|
903
|
+
const isOrcidURL = url.startsWith('https://orcid.org');
|
|
904
|
+
|
|
905
|
+
if (!isScicrunchURL && !isOrcidURL) {
|
|
906
|
+
console.warn(`Unsupported expert consultant URL: ${url}`);
|
|
907
|
+
continue;
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
// TEMPORARY: Use a CORS proxy for SciCrunch API requests
|
|
911
|
+
const corsProxy = this.envVars.CORS_PROXY_API;
|
|
912
|
+
const scicrunchAPIURL = (targetURL) => `${corsProxy}?target=${targetURL}.json`;
|
|
913
|
+
const orcidAPIURL = (targetURL) => targetURL.replace('orcid.org', 'pub.orcid.org/v2.1');
|
|
914
|
+
const APIURL = isScicrunchURL ? scicrunchAPIURL(url) : orcidAPIURL(url);
|
|
915
|
+
|
|
916
|
+
try {
|
|
917
|
+
const response = await fetch(APIURL, {
|
|
918
|
+
headers: {
|
|
919
|
+
'Accept': 'application/json'
|
|
920
|
+
}
|
|
921
|
+
});
|
|
922
|
+
const data = await response.json();
|
|
923
|
+
if (isScicrunchURL) {
|
|
924
|
+
const { hits } = data?.hits || {};
|
|
925
|
+
if (hits?.length) {
|
|
926
|
+
const name = hits[0]?._source?.item?.name;
|
|
927
|
+
if (name) {
|
|
928
|
+
const consultantIndex = this.expertConsultants.findIndex((consultant) => consultant.url === url);
|
|
929
|
+
if (consultantIndex !== -1) {
|
|
930
|
+
this.expertConsultants[consultantIndex].name = name;
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
} else {
|
|
935
|
+
const nameInfo = data?.person?.name;
|
|
936
|
+
if (nameInfo) {
|
|
937
|
+
const givenName = nameInfo['given-names']?.value || '';
|
|
938
|
+
const familyName = nameInfo['family-name']?.value || '';
|
|
939
|
+
const creditName = nameInfo['credit-name']?.value || '';
|
|
940
|
+
const fullName = creditName || `${givenName} ${familyName}`.trim();
|
|
941
|
+
if (fullName) {
|
|
942
|
+
const consultantIndex = this.expertConsultants.findIndex((consultant) => consultant.url === url);
|
|
943
|
+
if (consultantIndex !== -1) {
|
|
944
|
+
this.expertConsultants[consultantIndex].name = fullName;
|
|
945
|
+
const orcidId = data['orcid-identifier']?.path || '';
|
|
946
|
+
this.expertConsultants[consultantIndex].orcidId = orcidId;
|
|
947
|
+
const employmentSummary = data?.['activities-summary']?.['employments']?.['employment-summary'] || [];
|
|
948
|
+
const latestEmployment = employmentSummary[0] || {};
|
|
949
|
+
this.expertConsultants[consultantIndex].organization = latestEmployment?.organization?.name || '';
|
|
950
|
+
this.expertConsultants[consultantIndex].role = latestEmployment?.['role-title'] || '';
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
} catch (error) {
|
|
956
|
+
console.error('Error fetching expert consultant:', error);
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
this.updatedCopyContent = this.getUpdateCopyContent(this.storedReferences);
|
|
961
|
+
},
|
|
828
962
|
onConnectivityHovered: function (label) {
|
|
829
963
|
const payload = {
|
|
830
964
|
connectivityInfo: this.entry,
|
|
@@ -938,6 +1072,7 @@ export default {
|
|
|
938
1072
|
mounted: function () {
|
|
939
1073
|
this.updatedCopyContent = this.getUpdateCopyContent();
|
|
940
1074
|
this.updateTitleToggleVisibility();
|
|
1075
|
+
this.fetchExpertConsultants();
|
|
941
1076
|
|
|
942
1077
|
EventBus.on('connectivity-error', (errorInfo) => {
|
|
943
1078
|
const connectivityError = this.getConnectivityError(errorInfo);
|
|
@@ -1504,6 +1639,49 @@ export default {
|
|
|
1504
1639
|
}
|
|
1505
1640
|
}
|
|
1506
1641
|
|
|
1642
|
+
.consultant-block {
|
|
1643
|
+
padding-left: 1rem;
|
|
1644
|
+
|
|
1645
|
+
li + li {
|
|
1646
|
+
margin-top: 0.5rem;
|
|
1647
|
+
}
|
|
1648
|
+
|
|
1649
|
+
a {
|
|
1650
|
+
color: $app-primary-color;
|
|
1651
|
+
}
|
|
1652
|
+
}
|
|
1653
|
+
|
|
1654
|
+
.consultant-loading {
|
|
1655
|
+
margin: 0;
|
|
1656
|
+
position: relative;
|
|
1657
|
+
|
|
1658
|
+
span {
|
|
1659
|
+
position: static;
|
|
1660
|
+
visibility: hidden;
|
|
1661
|
+
opacity: 0;
|
|
1662
|
+
}
|
|
1663
|
+
|
|
1664
|
+
&::after {
|
|
1665
|
+
content: "";
|
|
1666
|
+
display: block;
|
|
1667
|
+
width: 100%;
|
|
1668
|
+
height: 100%;
|
|
1669
|
+
position: absolute;
|
|
1670
|
+
top: 0;
|
|
1671
|
+
left: 0;
|
|
1672
|
+
animation-duration: 3s;
|
|
1673
|
+
animation-fill-mode: forwards;
|
|
1674
|
+
animation-iteration-count: infinite;
|
|
1675
|
+
animation-name: loadingAnimation;
|
|
1676
|
+
animation-timing-function: linear;
|
|
1677
|
+
background: linear-gradient(to right,
|
|
1678
|
+
var(--el-bg-color-page) 5%,
|
|
1679
|
+
var(--el-color-info-light-8) 15%,
|
|
1680
|
+
var(--el-bg-color-page) 30%
|
|
1681
|
+
);
|
|
1682
|
+
}
|
|
1683
|
+
}
|
|
1684
|
+
|
|
1507
1685
|
.alert-chip {
|
|
1508
1686
|
margin-left: 5px;
|
|
1509
1687
|
background-color: $app-primary-color;
|
|
@@ -1527,4 +1705,23 @@ export default {
|
|
|
1527
1705
|
margin: 0;
|
|
1528
1706
|
}
|
|
1529
1707
|
}
|
|
1708
|
+
|
|
1709
|
+
.sr-only {
|
|
1710
|
+
clip: rect(0 0 0 0);
|
|
1711
|
+
clip-path: inset(50%);
|
|
1712
|
+
height: 1px;
|
|
1713
|
+
overflow: hidden;
|
|
1714
|
+
position: absolute;
|
|
1715
|
+
white-space: nowrap;
|
|
1716
|
+
width: 1px;
|
|
1717
|
+
}
|
|
1718
|
+
|
|
1719
|
+
@keyframes loadingAnimation {
|
|
1720
|
+
0% {
|
|
1721
|
+
background-position: -30vw 0;
|
|
1722
|
+
}
|
|
1723
|
+
100% {
|
|
1724
|
+
background-position: 70vw 0;
|
|
1725
|
+
}
|
|
1726
|
+
}
|
|
1530
1727
|
</style>
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="contributor-item">
|
|
3
|
+
<el-popover
|
|
4
|
+
placement="top-start"
|
|
5
|
+
width="320"
|
|
6
|
+
trigger="hover"
|
|
7
|
+
popper-class="contributor-popover"
|
|
8
|
+
:teleported="false"
|
|
9
|
+
>
|
|
10
|
+
<div class="popover-content">
|
|
11
|
+
<div class="popover-name">{{ contributor.name }}</div>
|
|
12
|
+
<div class="popover-url" v-if="contributor.orcidId">
|
|
13
|
+
<strong>ORCID iD</strong>:
|
|
14
|
+
<a :href="contributor.url" target="_blank">{{ orcidId }}</a>
|
|
15
|
+
</div>
|
|
16
|
+
<div class="popover-url" v-if="rrid">
|
|
17
|
+
<strong>RRID</strong>:
|
|
18
|
+
<a :href="contributor.url" target="_blank">{{ rrid }}</a>
|
|
19
|
+
</div>
|
|
20
|
+
<div class="popover-organization" v-if="contributor.organization">
|
|
21
|
+
<strong>Organization</strong>: {{ contributor.organization }}
|
|
22
|
+
</div>
|
|
23
|
+
<div class="popover-role" v-if="contributor.role">
|
|
24
|
+
<strong>Title</strong>: {{ contributor.role }}
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
<template #reference>
|
|
28
|
+
<span>{{ contributor.name }}</span>
|
|
29
|
+
</template>
|
|
30
|
+
</el-popover>
|
|
31
|
+
</div>
|
|
32
|
+
</template>
|
|
33
|
+
|
|
34
|
+
<script>
|
|
35
|
+
export default {
|
|
36
|
+
name: 'ContributorItem',
|
|
37
|
+
|
|
38
|
+
props: {
|
|
39
|
+
contributor: {
|
|
40
|
+
type: Object,
|
|
41
|
+
default: () => ({})
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
computed: {
|
|
46
|
+
orcidId: function () {
|
|
47
|
+
return this.contributor.orcidId || ''
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
rrid: function () {
|
|
51
|
+
return this.contributor.url.indexOf('RRID:') > -1
|
|
52
|
+
? 'RRID:' + this.contributor.url.split('RRID:')[1]
|
|
53
|
+
: ''
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
</script>
|
|
58
|
+
|
|
59
|
+
<style lang="scss" scoped>
|
|
60
|
+
@import '../assets/_variables.scss';
|
|
61
|
+
|
|
62
|
+
.contributor-item {
|
|
63
|
+
display: inline;
|
|
64
|
+
text-decoration: underline;
|
|
65
|
+
color: $app-primary-color;
|
|
66
|
+
}
|
|
67
|
+
</style>
|
|
68
|
+
|
|
69
|
+
<style lang="scss">
|
|
70
|
+
@import '../assets/_variables.scss';
|
|
71
|
+
|
|
72
|
+
.contributor-popover.el-popover {
|
|
73
|
+
font-family: $font-family;
|
|
74
|
+
background: #f3ecf6 !important;
|
|
75
|
+
border: 1px solid $app-primary-color !important;
|
|
76
|
+
border-radius: 4px !important;
|
|
77
|
+
color: $grey !important;
|
|
78
|
+
text-transform: none !important;
|
|
79
|
+
font-weight: 400;
|
|
80
|
+
|
|
81
|
+
.el-popper__arrow::before {
|
|
82
|
+
background: #f3ecf6 !important;
|
|
83
|
+
border-color: $app-primary-color !important;
|
|
84
|
+
background-color: #ffffff;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.popover-content {
|
|
88
|
+
line-height: inherit;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.popover-name {
|
|
92
|
+
font-size: 1.3em;
|
|
93
|
+
margin-bottom: 0.25em;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.popover-url {
|
|
97
|
+
a {
|
|
98
|
+
color: $app-primary-color;
|
|
99
|
+
word-break: break-all;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.popover-organization,
|
|
104
|
+
.popover-role {
|
|
105
|
+
word-break: normal;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
</style>
|
package/src/components.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ declare module 'vue' {
|
|
|
14
14
|
ConnectivityCard: typeof import('./components/ConnectivityCard.vue')['default']
|
|
15
15
|
ConnectivityExplorer: typeof import('./components/ConnectivityExplorer.vue')['default']
|
|
16
16
|
ConnectivityInfo: typeof import('./components/ConnectivityInfo.vue')['default']
|
|
17
|
+
ContributorItem: typeof import('./components/ContributorItem.vue')['default']
|
|
17
18
|
DatasetCard: typeof import('./components/DatasetCard.vue')['default']
|
|
18
19
|
DatasetExplorer: typeof import('./components/DatasetExplorer.vue')['default']
|
|
19
20
|
ElButton: typeof import('element-plus/es')['ElButton']
|