@abi-software/map-utilities 1.3.2 → 1.3.3-beta.1

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-utilities",
3
- "version": "1.3.2",
3
+ "version": "1.3.3-beta.1",
4
4
  "files": [
5
5
  "dist/*",
6
6
  "src/*",
@@ -30,6 +30,11 @@
30
30
  },
31
31
  "dependencies": {
32
32
  "@abi-software/svg-sprite": "^1.0.1",
33
+ "@citation-js/core": "^0.7.14",
34
+ "@citation-js/plugin-bibtex": "^0.7.17",
35
+ "@citation-js/plugin-csl": "^0.7.14",
36
+ "@citation-js/plugin-doi": "^0.7.16",
37
+ "@citation-js/plugin-pubmed": "^0.3.0",
33
38
  "@element-plus/icons-vue": "^2.3.1",
34
39
  "cytoscape": "^3.30.2",
35
40
  "element-plus": "2.8.4",
@@ -1,6 +1,10 @@
1
1
  <template>
2
2
  <div class="connectivity-graph" v-loading="loading" ref="connectivityGraphRef">
3
3
 
4
+ <div class="sckan-version">
5
+ SCKAN Release: {{ this.selectedSource }}
6
+ </div>
7
+
4
8
  <div ref="graphCanvas" class="graph-canvas"></div>
5
9
 
6
10
  <div class="control-panel control-panel-tools">
@@ -149,6 +153,10 @@ export default {
149
153
  type: String,
150
154
  default: '',
151
155
  },
156
+ sckanVersion: {
157
+ type: String,
158
+ default: '',
159
+ },
152
160
  selectedConnectivityData: {
153
161
  type: Array,
154
162
  default: [],
@@ -196,6 +204,12 @@ export default {
196
204
  if (selectedSource) {
197
205
  this.selectedSource = selectedSource;
198
206
  }
207
+ // Update knowledge source if SCKAN version is provided
208
+ if (this.sckanVersion) {
209
+ this.selectedSource = this.sckanVersion;
210
+ sessionStorage.setItem('connectivity-graph-source', this.selectedSource);
211
+ this.updateCacheExpiry();
212
+ }
199
213
  if (pathList) {
200
214
  this.pathList = JSON.parse(pathList);
201
215
  }
@@ -207,6 +221,13 @@ export default {
207
221
  this.schemaVersion = schemaVersion;
208
222
  }
209
223
  },
224
+ isValidKnowledgeSource: function () {
225
+ const selectedSource = sessionStorage.getItem('connectivity-graph-source');
226
+ if (this.sckanVersion && (this.sckanVersion !== selectedSource)) {
227
+ return false;
228
+ }
229
+ return true;
230
+ },
210
231
  removeAllCacheData: function () {
211
232
  const keys = [
212
233
  'connectivity-graph-expiry',
@@ -222,8 +243,9 @@ export default {
222
243
  refreshCache: function () {
223
244
  const expiry = sessionStorage.getItem('connectivity-graph-expiry');
224
245
  const now = new Date();
246
+ const validKnowledgeSource = this.isValidKnowledgeSource();
225
247
 
226
- if (now.getTime() > expiry) {
248
+ if (now.getTime() > expiry || !validKnowledgeSource) {
227
249
  this.removeAllCacheData();
228
250
  }
229
251
  },
@@ -641,6 +663,16 @@ export default {
641
663
  white-space: nowrap;
642
664
  width: 1px;
643
665
  }
666
+
667
+ .sckan-version {
668
+ position: absolute;
669
+ bottom: 0;
670
+ right: 0;
671
+ margin-bottom: -22px;
672
+ font-size: 12px;
673
+ font-style: italic;
674
+ color: gray;
675
+ }
644
676
  </style>
645
677
 
646
678
  <style lang="scss">
@@ -6,7 +6,7 @@
6
6
  <CopyToClipboard label="Copy list to clipboard" :content="referecesListContent" />
7
7
  </div>
8
8
  </div>
9
- <div class="citation-tabs" v-if="referencesWithDOI">
9
+ <div class="citation-tabs" v-if="useDOIFormatter ? referencesWithDOI : pubMedReferences.length">
10
10
  <el-button
11
11
  link
12
12
  v-for="citationOption of citationOptions"
@@ -21,7 +21,10 @@
21
21
  <li
22
22
  v-for="reference of pubMedReferences"
23
23
  :key="reference.id"
24
- :class="{'loading': reference.citation && !reference.citation.error && reference.citation[citationType] === ''}"
24
+ :class="{
25
+ 'loading': reference.citation && !reference.citation.error && reference.citation[citationType] === '',
26
+ 'error': reference.citation && reference.citation.error
27
+ }"
25
28
  >
26
29
  <template v-if="reference.citation">
27
30
 
@@ -66,7 +69,7 @@
66
69
 
67
70
  <script>
68
71
  import CopyToClipboard from '../CopyToClipboard/CopyToClipboard.vue';
69
- import { delay } from '../utilities';
72
+ import { delay, getCitationById } from '../utilities';
70
73
 
71
74
  const CROSSCITE_API_HOST = 'https://citation.doi.org';
72
75
  const CITATION_OPTIONS = [
@@ -92,11 +95,18 @@ const LOADING_DELAY = 600;
92
95
 
93
96
  export default {
94
97
  name: "ExternalResourceCard",
98
+ components: {
99
+ CopyToClipboard,
100
+ },
95
101
  props: {
96
102
  resources: {
97
103
  type: Array,
98
104
  default: () => [],
99
105
  },
106
+ useDOIFormatter: {
107
+ type: Boolean,
108
+ default: true,
109
+ }
100
110
  },
101
111
  data: function () {
102
112
  return {
@@ -288,7 +298,14 @@ export default {
288
298
 
289
299
  if (type === 'doi' || doi) {
290
300
  const doiID = type === 'doi' ? id : doi;
291
- this.getCitationTextByDOI(doiID).then((text) => {
301
+ const fetchCitationFromAPI = this.useDOIFormatter ?
302
+ this.getCitationTextByDOI(doiID) :
303
+ getCitationById(doiID, {
304
+ type: 'doi',
305
+ format: citationType
306
+ });
307
+
308
+ fetchCitationFromAPI.then((text) => {
292
309
  const formattedText = this.replaceLinkInText(text);
293
310
  reference.citation[citationType] = formattedText;
294
311
  this.updateCopyContents();
@@ -299,45 +316,61 @@ export default {
299
316
  };
300
317
  });
301
318
  } else if (type === 'pmid') {
302
- this.getDOIFromPubMedID(id).then((data) => {
303
- if (data?.result) {
304
- const resultObj = data.result[id];
305
- const articleIDs = resultObj?.articleids || [];
306
- const doiObj = articleIDs.find((item) => item.idtype === 'doi');
307
- const doiID = doiObj?.value;
308
-
309
- if (doiID) {
310
- reference['doi'] = doiID;
311
- this.getCitationTextByDOI(doiID).then((text) => {
312
- const formattedText = this.replaceLinkInText(text);
319
+ if (this.useDOIFormatter) {
320
+ this.getDOIFromPubMedID(id).then((data) => {
321
+ if (data?.result) {
322
+ const resultObj = data.result[id];
323
+ const articleIDs = resultObj?.articleids || [];
324
+ const doiObj = articleIDs.find((item) => item.idtype === 'doi');
325
+ const doiID = doiObj?.value;
326
+
327
+ if (doiID) {
328
+ reference['doi'] = doiID;
329
+ this.getCitationTextByDOI(doiID).then((text) => {
330
+ const formattedText = this.replaceLinkInText(text);
331
+ reference.citation[citationType] = formattedText;
332
+ this.updateCopyContents();
333
+ }).catch((error) => {
334
+ reference.citation['error'] = {
335
+ type: citationType,
336
+ ref: 'doi',
337
+ };
338
+ });
339
+ } else {
340
+ // If there has no doi in PubMed
341
+ const { title, pubdate, authors } = resultObj;
342
+ const authorNames = authors ? authors.map((author) => author.name) : [];
343
+ const formattedText = this.formatCopyReference({
344
+ title: title || '',
345
+ date: pubdate || '',
346
+ authors: authorNames,
347
+ url: `https://pubmed.ncbi.nlm.nih.gov/${id}`,
348
+ });
313
349
  reference.citation[citationType] = formattedText;
314
350
  this.updateCopyContents();
315
- }).catch((error) => {
316
- reference.citation['error'] = {
317
- type: citationType,
318
- ref: 'doi',
319
- };
320
- });
321
- } else {
322
- // If there has no doi in PubMed
323
- const { title, pubdate, authors } = resultObj;
324
- const authorNames = authors ? authors.map((author) => author.name) : [];
325
- const formattedText = this.formatCopyReference({
326
- title: title || '',
327
- date: pubdate || '',
328
- authors: authorNames,
329
- url: `https://pubmed.ncbi.nlm.nih.gov/${id}`,
330
- });
331
- reference.citation[citationType] = formattedText;
332
- this.updateCopyContents();
351
+ }
333
352
  }
334
- }
335
- }).catch((error) => {
336
- reference.citation['error'] = {
337
- type: citationType,
338
- ref: 'pubmed',
339
- };
340
- });
353
+ }).catch((error) => {
354
+ reference.citation['error'] = {
355
+ type: citationType,
356
+ ref: 'pubmed',
357
+ };
358
+ });
359
+ } else {
360
+ getCitationById(id, {
361
+ type: 'pmid',
362
+ format: citationType
363
+ }).then((text) => {
364
+ const formattedText = this.replaceLinkInText(text);
365
+ reference.citation[citationType] = formattedText;
366
+ this.updateCopyContents();
367
+ }).catch((error) => {
368
+ reference.citation['error'] = {
369
+ type: citationType,
370
+ ref: 'pubmed',
371
+ };
372
+ });
373
+ }
341
374
  }
342
375
  }
343
376
  },
@@ -582,6 +615,13 @@ export default {
582
615
  }
583
616
  }
584
617
 
618
+ &.error {
619
+ font-style: italic;
620
+ color: var(--el-color-info);
621
+ border: 1px dotted red;
622
+ background-color: transparent;
623
+ }
624
+
585
625
  :deep(.copy-clipboard-button) {
586
626
  position: absolute;
587
627
  bottom: 0.25rem;
@@ -1,3 +1,9 @@
1
+ import { Cite, plugins } from '@citation-js/core';
2
+ import '@citation-js/plugin-doi';
3
+ import '@citation-js/plugin-csl';
4
+ import '@citation-js/plugin-bibtex';
5
+ import '@citation-js/plugin-pubmed';
6
+
1
7
  const capitalise = term => {
2
8
  if (term)
3
9
  return term.charAt(0).toUpperCase() + term.slice(1);
@@ -48,8 +54,42 @@ const delay = (ms) => {
48
54
  return new Promise(resolve => setTimeout(resolve, ms));
49
55
  };
50
56
 
57
+ /**
58
+ * @param {id} id - DOI or PMID
59
+ * @param {options:type} type - type of the ID, e.g., 'pmid'
60
+ * @param {options:format} format - 'apa' (default), 'chicago', 'ieee', 'bibtex', etc.
61
+ * @returns {citation} formatted citation text
62
+ */
63
+ const getCitationById = async (id, { type, format }) => {
64
+ // because 'chicago' and 'ieee' are not in citation.js default styles
65
+ if ((format !== 'bibtex') && (format !== 'apa')) {
66
+ const xml = `https://raw.githubusercontent.com/citation-style-language/styles/refs/heads/master/${format}.csl`;
67
+ const response = await fetch(xml);
68
+ const template = await response.text();
69
+ let config = plugins.config.get('@csl');
70
+ config.templates.add(format, template);
71
+ }
72
+
73
+ const option = {};
74
+
75
+ if (type === 'pmid') {
76
+ option['forceType'] = '@pubmed/id';
77
+ }
78
+
79
+ const cite = await Cite.async(id, option);
80
+ const citation = (format === 'bibtex') ?
81
+ cite.format(format) :
82
+ cite.format('bibliography', {
83
+ format: 'html',
84
+ template: format || 'apa', // default as 'apa' style
85
+ lang: 'en-US'
86
+ })
87
+ return citation;
88
+ };
89
+
51
90
  export {
52
91
  capitalise,
53
92
  xmlToJSON,
54
93
  delay,
94
+ getCitationById,
55
95
  };
@@ -14,9 +14,7 @@ declare module 'vue' {
14
14
  CreateTooltipContent: typeof import('./components/Tooltip/CreateTooltipContent.vue')['default']
15
15
  DrawToolbar: typeof import('./components/DrawToolbar/DrawToolbar.vue')['default']
16
16
  ElButton: typeof import('element-plus/es')['ElButton']
17
- ElCard: typeof import('element-plus/es')['ElCard']
18
17
  ElCol: typeof import('element-plus/es')['ElCol']
19
- ElColorPicker: typeof import('element-plus/es')['ElColorPicker']
20
18
  ElContainer: typeof import('element-plus/es')['ElContainer']
21
19
  ElHeader: typeof import('element-plus/es')['ElHeader']
22
20
  ElIcon: typeof import('element-plus/es')['ElIcon']
@@ -30,7 +28,6 @@ declare module 'vue' {
30
28
  ElIconFinished: typeof import('@element-plus/icons-vue')['Finished']
31
29
  ElIconLock: typeof import('@element-plus/icons-vue')['Lock']
32
30
  ElIconUnlock: typeof import('@element-plus/icons-vue')['Unlock']
33
- ElIconWarning: typeof import('@element-plus/icons-vue')['Warning']
34
31
  ElIconZoomIn: typeof import('@element-plus/icons-vue')['ZoomIn']
35
32
  ElIconZoomOut: typeof import('@element-plus/icons-vue')['ZoomOut']
36
33
  ElInput: typeof import('element-plus/es')['ElInput']
@@ -40,7 +37,6 @@ declare module 'vue' {
40
37
  ElRow: typeof import('element-plus/es')['ElRow']
41
38
  ElSelect: typeof import('element-plus/es')['ElSelect']
42
39
  ElTooltip: typeof import('element-plus/es')['ElTooltip']
43
- ElTree: typeof import('element-plus/es')['ElTree']
44
40
  ExternalResourceCard: typeof import('./components/Tooltip/ExternalResourceCard.vue')['default']
45
41
  HelpModeDialog: typeof import('./components/HelpModeDialog/HelpModeDialog.vue')['default']
46
42
  ProvenancePopup: typeof import('./components/Tooltip/ProvenancePopup.vue')['default']