@abi-software/map-side-bar 2.14.8-demo.5 → 2.14.8-demo.7

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": "2.14.8-demo.5",
3
+ "version": "2.14.8-demo.7",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
package/src/App.vue CHANGED
@@ -137,7 +137,6 @@ 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,
141
140
  },
142
141
  connectivityEntry: [],
143
142
  createData: {
@@ -310,12 +310,21 @@
310
310
  </div>
311
311
  <ul class="block consultant-block">
312
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>
313
+ <contributor-item :contributor="consultant" v-if="consultant.name" />
314
+ <div class="consultant-loading" v-else-if="!consultant.error">
317
315
  <span>Loading {{ consultant.url }}</span>
318
316
  </div>
317
+ <div class="consultant-error" v-if="consultant.error">
318
+ <span v-if="consultant.errorMessage">{{ consultant.errorMessage }}</span>
319
+ <span v-else>Sorry, something went wrong.</span>
320
+ <template v-if="consultant.refreshable">
321
+ <br />
322
+ Please try again.
323
+ <span class="reload-button" @click="reloadConsultant(consultant)">
324
+ Reload
325
+ </span>
326
+ </template>
327
+ </div>
319
328
  </li>
320
329
  </ul>
321
330
  </div>
@@ -896,67 +905,148 @@ export default {
896
905
  return data
897
906
  },
898
907
  fetchExpertConsultants: async function () {
899
- this.expertConsultants = this.expertConsultantURLs.map(url => ({ name: '', url }));
908
+ this.expertConsultants = this.expertConsultantURLs.map((url) => ({
909
+ name: '',
910
+ url,
911
+ error: false,
912
+ errorMessage: '',
913
+ refreshable: false,
914
+ }));
900
915
 
901
916
  for (const url of this.expertConsultantURLs) {
902
- const isScicrunchURL = url.startsWith('https://scicrunch.org');
903
- const isOrcidURL = url.startsWith('https://orcid.org');
917
+ await this.fetchSingleExpertConsultant(url);
918
+ }
919
+
920
+ this.updatedCopyContent = this.getUpdateCopyContent(this.storedReferences);
921
+ },
922
+ buildExpertConsultantRequestInfo: function (url) {
923
+ const scicrunchBase = 'https://scicrunch.org';
924
+ const orcidBase = 'https://orcid.org';
925
+ const orcidAPIBase = 'https://pub.orcid.org/v2.1';
926
+ const apiLocationBase = (this.envVars.API_LOCATION ?? '').replace(/\/?$/, '/');
927
+ const isScicrunchURL = url.startsWith(scicrunchBase);
928
+ const isOrcidURL = url.startsWith(orcidBase);
929
+
930
+ if (!isScicrunchURL && !isOrcidURL) {
931
+ return null;
932
+ }
933
+
934
+ const APIURL = isScicrunchURL
935
+ ? url.replace(scicrunchBase, `${apiLocationBase}scicrunch`)
936
+ : url.replace(orcidBase, orcidAPIBase);
937
+
938
+ return {
939
+ APIURL,
940
+ isScicrunchURL,
941
+ };
942
+ },
943
+ fetchSingleExpertConsultant: async function (url) {
944
+ const requestInfo = this.buildExpertConsultantRequestInfo(url);
945
+ if (!requestInfo) {
946
+ console.warn(`Unsupported expert consultant URL: ${url}`);
947
+ this.updateExpertConsultantByURL(url, {
948
+ name: '',
949
+ error: true,
950
+ errorMessage: 'Unsupported expert consultant URL.',
951
+ refreshable: false,
952
+ orcidId: '',
953
+ organization: '',
954
+ role: '',
955
+ });
956
+ return;
957
+ }
904
958
 
905
- if (!isScicrunchURL && !isOrcidURL) {
906
- console.warn(`Unsupported expert consultant URL: ${url}`);
907
- continue;
959
+ const { APIURL, isScicrunchURL } = requestInfo;
960
+
961
+ // Reset the consultant data before fetching
962
+ this.updateExpertConsultantByURL(url, {
963
+ name: '',
964
+ error: false,
965
+ errorMessage: '',
966
+ refreshable: false,
967
+ orcidId: '',
968
+ organization: '',
969
+ role: '',
970
+ });
971
+
972
+ try {
973
+ const response = await fetch(APIURL, {
974
+ headers: {
975
+ Accept: 'application/json',
976
+ },
977
+ });
978
+
979
+ if (!response.ok) {
980
+ throw new Error(`Response status: ${response.status}`);
908
981
  }
909
982
 
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);
983
+ const data = await response.json();
915
984
 
916
- try {
917
- const response = await fetch(APIURL, {
918
- headers: {
919
- 'Accept': 'application/json'
920
- }
985
+ if (isScicrunchURL) {
986
+ const { hits } = data?.hits || {};
987
+ const name = hits?.[0]?._source?.item?.name || '';
988
+
989
+ if (!name) {
990
+ throw new Error('No consultant data returned from SciCrunch.');
991
+ }
992
+
993
+ this.updateExpertConsultantByURL(url, {
994
+ name,
995
+ error: false,
996
+ errorMessage: '',
997
+ refreshable: false,
921
998
  });
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
- }
999
+ } else {
1000
+ const nameInfo = data?.person?.name;
1001
+ const givenName = nameInfo?.['given-names']?.value || '';
1002
+ const familyName = nameInfo?.['family-name']?.value || '';
1003
+ const creditName = nameInfo?.['credit-name']?.value || '';
1004
+ const fullName = creditName || `${givenName} ${familyName}`.trim();
1005
+
1006
+ if (!fullName) {
1007
+ throw new Error('No consultant data returned from ORCID.');
954
1008
  }
955
- } catch (error) {
956
- console.error('Error fetching expert consultant:', error);
1009
+
1010
+ const orcidId = data?.['orcid-identifier']?.path || '';
1011
+ const employmentSummary = data?.['activities-summary']?.['employments']?.['employment-summary'] || [];
1012
+ const latestEmployment = employmentSummary[0] || {};
1013
+
1014
+ this.updateExpertConsultantByURL(url, {
1015
+ name: fullName,
1016
+ error: false,
1017
+ errorMessage: '',
1018
+ refreshable: false,
1019
+ orcidId,
1020
+ organization: latestEmployment?.organization?.name || '',
1021
+ role: latestEmployment?.['role-title'] || '',
1022
+ });
957
1023
  }
1024
+ } catch (error) {
1025
+ console.error('Error fetching expert consultant:', error);
1026
+ this.updateExpertConsultantByURL(url, {
1027
+ name: '',
1028
+ error: true,
1029
+ errorMessage: 'Failed to fetch expert consultant data.',
1030
+ refreshable: true,
1031
+ orcidId: '',
1032
+ organization: '',
1033
+ role: '',
1034
+ });
1035
+ }
1036
+ },
1037
+ updateExpertConsultantByURL: function (url, fields = {}) {
1038
+ const consultantIndex = this.expertConsultants.findIndex((consultant) => consultant.url === url);
1039
+ if (consultantIndex === -1) {
1040
+ return;
958
1041
  }
959
1042
 
1043
+ this.expertConsultants.splice(consultantIndex, 1, {
1044
+ ...this.expertConsultants[consultantIndex],
1045
+ ...fields,
1046
+ });
1047
+ },
1048
+ reloadConsultant: async function (consultant) {
1049
+ await this.fetchSingleExpertConsultant(consultant.url);
960
1050
  this.updatedCopyContent = this.getUpdateCopyContent(this.storedReferences);
961
1051
  },
962
1052
  onConnectivityHovered: function (label) {
@@ -1682,6 +1772,14 @@ export default {
1682
1772
  }
1683
1773
  }
1684
1774
 
1775
+ .consultant-error {
1776
+ padding: 0.25rem 0.5rem;
1777
+ font-style: italic;
1778
+ color: var(--el-color-info);
1779
+ border: 1px dotted red;
1780
+ border-radius: 4px;
1781
+ }
1782
+
1685
1783
  .alert-chip {
1686
1784
  margin-left: 5px;
1687
1785
  background-color: $app-primary-color;
@@ -1716,6 +1814,12 @@ export default {
1716
1814
  width: 1px;
1717
1815
  }
1718
1816
 
1817
+ .reload-button {
1818
+ color: $app-primary-color;
1819
+ text-decoration: underline;
1820
+ cursor: pointer;
1821
+ }
1822
+
1719
1823
  @keyframes loadingAnimation {
1720
1824
  0% {
1721
1825
  background-position: -30vw 0;