@abi-software/map-side-bar 2.18.0 → 2.19.1-demo.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.
Files changed (41) hide show
  1. package/.postcssrc.json +5 -5
  2. package/README.md +8 -9
  3. package/cypress.config.js +6 -7
  4. package/dist/map-side-bar.js +6890 -6026
  5. package/dist/map-side-bar.umd.cjs +65 -62
  6. package/dist/style.css +1 -1
  7. package/eslint.config.js +44 -9
  8. package/package.json +10 -3
  9. package/reporter-config.json +1 -1
  10. package/src/App.vue +89 -80
  11. package/src/algolia/algolia.js +173 -167
  12. package/src/algolia/utils.js +34 -38
  13. package/src/assets/_variables.scss +12 -10
  14. package/src/assets/connectivity-explorer.scss +1 -1
  15. package/src/assets/fonts.scss +0 -1
  16. package/src/assets/searchPopover.scss +1 -2
  17. package/src/components/AnnotationTool.vue +9 -32
  18. package/src/components/BadgesGroup.vue +29 -32
  19. package/src/components/CellCard.vue +992 -0
  20. package/src/components/CellCardExplorer.vue +879 -0
  21. package/src/components/ConnectivityCard.vue +22 -19
  22. package/src/components/ConnectivityExplorer.vue +109 -130
  23. package/src/components/ConnectivityInfo.vue +142 -171
  24. package/src/components/ContributorItem.vue +15 -11
  25. package/src/components/DatasetCard.vue +166 -201
  26. package/src/components/DatasetExplorer.vue +160 -201
  27. package/src/components/ImageGallery.vue +35 -36
  28. package/src/components/SearchFilters.vue +384 -407
  29. package/src/components/SearchHistory.vue +69 -103
  30. package/src/components/SideBar.vue +186 -94
  31. package/src/components/Tabs.vue +25 -21
  32. package/src/components/icons/IconOpenExternal.vue +23 -0
  33. package/src/components/index.js +3 -5
  34. package/src/components/species-map.js +7 -7
  35. package/src/components.d.ts +3 -0
  36. package/src/exampleConnectivityInput.js +310 -318
  37. package/src/main.js +6 -6
  38. package/src/mixins/S3Bucket.vue +10 -13
  39. package/src/utils/common.js +59 -0
  40. package/vite.config.js +62 -61
  41. package/vuese-generator.js +47 -55
@@ -48,12 +48,7 @@
48
48
  </div>
49
49
  </div>
50
50
  <div class="title-buttons">
51
- <el-popover
52
- width="auto"
53
- trigger="hover"
54
- :teleported="false"
55
- popper-class="popover-map-pin"
56
- >
51
+ <el-popover width="auto" trigger="hover" :teleported="false" popper-class="popover-map-pin">
57
52
  <template #reference>
58
53
  <el-button class="button-circle secondary" circle @click="showConnectivity">
59
54
  <el-icon color="#8300bf">
@@ -61,9 +56,7 @@
61
56
  </el-icon>
62
57
  </el-button>
63
58
  </template>
64
- <span>
65
- Show connectivity on map
66
- </span>
59
+ <span>Show connectivity on map</span>
67
60
  </el-popover>
68
61
  <CopyToClipboard @copied="onCopied" :content="updatedCopyContent" />
69
62
  <template v-if="withCloseButton">
@@ -86,7 +79,10 @@
86
79
  </div>
87
80
  </div>
88
81
 
89
- <div class="content-container population-details" :class="{'flex-row': hasSingleConnectivityList}">
82
+ <div
83
+ class="content-container population-details"
84
+ :class="{ 'flex-row': hasSingleConnectivityList }"
85
+ >
90
86
  <div class="block attribute-title-container">
91
87
  <span class="attribute-title">Population Details</span>
92
88
  <el-popover
@@ -100,12 +96,11 @@
100
96
  <el-icon class="info"><el-icon-warning /></el-icon>
101
97
  </template>
102
98
  <span v-if="hasSingleConnectivityList" style="word-break: keep-all">
103
- This list is ordered alphabetically. Switch to graph view for path details,
104
- and use the legend below for reconciliation status.
99
+ This list is ordered alphabetically. Switch to graph view for path details, and use the
100
+ legend below for reconciliation status.
105
101
  </span>
106
102
  <span v-else style="word-break: keep-all">
107
- This list is ordered alphabetically,
108
- switch to graph view for path details.
103
+ This list is ordered alphabetically, switch to graph view for path details.
109
104
  </span>
110
105
  <div v-if="hasSingleConnectivityList" class="connectivity-legends">
111
106
  <div class="legend-title">Legend</div>
@@ -138,9 +133,11 @@
138
133
  <el-icon class="info"><el-icon-warning /></el-icon>
139
134
  </template>
140
135
  <span style="word-break: keep-all">
141
- <strong>Map</strong> - connectivity as defined in active map.
142
- <br>
143
- <strong>SCKAN</strong> - connectivity as defined in SCKAN.
136
+ <strong>Map</strong>
137
+ - connectivity as defined in active map.
138
+ <br />
139
+ <strong>SCKAN</strong>
140
+ - connectivity as defined in SCKAN.
144
141
  </span>
145
142
  </el-popover>
146
143
  </span>
@@ -149,7 +146,7 @@
149
146
  <el-radio value="sckan">SCKAN</el-radio>
150
147
  </el-radio-group>
151
148
  </div>
152
- <div class="population-details-view" :class="{'align-right': hasSingleConnectivityList}">
149
+ <div class="population-details-view" :class="{ 'align-right': hasSingleConnectivityList }">
153
150
  <el-button
154
151
  :class="activeView === 'listView' ? 'button' : 'el-button-secondary'"
155
152
  @click="switchConnectivityView('listView')"
@@ -170,16 +167,12 @@
170
167
  <div class="attribute-title-container">
171
168
  <span class="attribute-title">Nerves</span>
172
169
  </div>
173
- <div v-for="(nerve, i) in entry['nerve-label']">
174
- <div
175
- class="attribute-content"
176
- :origin-item-label="nerve.nerve"
177
- :key="nerve.nerve"
178
- >
170
+ <div v-for="(nerve, i) in entry['nerve-label']" :key="i">
171
+ <div class="attribute-content" :origin-item-label="nerve.nerve" :key="nerve.nerve">
179
172
  <span>{{ capitalise(nerve.nerve) }}</span>
180
173
  </div>
181
174
  <div
182
- v-for="(subNerve, i) in nerve.subNerves"
175
+ v-for="subNerve in nerve.subNerves"
183
176
  class="attribute-content"
184
177
  style="margin-left: 1rem"
185
178
  :origin-item-label="subNerve"
@@ -205,7 +198,10 @@
205
198
  </div>
206
199
  </div>
207
200
 
208
- <div class="content-container content-container-connectivity" v-show="activeView === 'listView'">
201
+ <div
202
+ class="content-container content-container-connectivity"
203
+ v-show="activeView === 'listView'"
204
+ >
209
205
  <!-- TODO: To use only one component when the data is ready -->
210
206
  <template v-if="hasSingleConnectivityList">
211
207
  <connectivity-reconciliation-list
@@ -248,14 +244,12 @@
248
244
  </template>
249
245
  </div>
250
246
 
251
- <div class="content-container content-container-connectivity" v-show="activeView === 'graphView'">
247
+ <div
248
+ class="content-container content-container-connectivity"
249
+ v-show="activeView === 'graphView'"
250
+ >
252
251
  <template v-if="graphViewLoaded">
253
- <el-button
254
- class="button"
255
- @click="openGraphInViewer"
256
- >
257
- Open in viewer
258
- </el-button>
252
+ <el-button class="button" @click="openGraphInViewer">Open in viewer</el-button>
259
253
  <connectivity-graph
260
254
  v-loading="connectivityLoading"
261
255
  :key="`${connectivityKey}graph`"
@@ -297,8 +291,10 @@
297
291
  <span class="attribute-title">Notes</span>
298
292
  </div>
299
293
  <div class="block">
300
- <div class="alert-block"
301
- v-for="alert in entry.featuresAlert"
294
+ <div
295
+ class="alert-block"
296
+ v-for="(alert, alertIndex) in entry.featuresAlert"
297
+ :key="alertIndex"
302
298
  v-html="formatAlertText(alert)"
303
299
  ></div>
304
300
  </div>
@@ -320,9 +316,7 @@
320
316
  <template v-if="consultant.refreshable">
321
317
  <br />
322
318
  Please try again.
323
- <span class="reload-button" @click="reloadConsultant(consultant)">
324
- Reload
325
- </span>
319
+ <span class="reload-button" @click="reloadConsultant(consultant)">Reload</span>
326
320
  </template>
327
321
  </div>
328
322
  </li>
@@ -332,21 +326,15 @@
332
326
  </template>
333
327
 
334
328
  <script>
335
- /* eslint-disable no-alert, no-console */
336
329
  import {
337
330
  Warning as ElIconWarning,
338
331
  Location as ElIconLocation,
339
332
  Search as ElIconSearch,
340
333
  ArrowDown as ElIconArrowDown,
341
334
  ArrowUp as ElIconArrowUp,
342
- } from '@element-plus/icons-vue'
343
- import {
344
- ElButton as Button,
345
- ElContainer as Container,
346
- ElIcon as Icon,
347
- } from 'element-plus'
348
- import ContributorItem from './ContributorItem.vue'
349
- import EventBus from './EventBus.js'
335
+ } from '@element-plus/icons-vue';
336
+ import ContributorItem from './ContributorItem.vue';
337
+ import EventBus from './EventBus.js';
350
338
  import {
351
339
  CopyToClipboard,
352
340
  ConnectivityGraph,
@@ -355,24 +343,21 @@ import {
355
343
  ExternalResourceCard,
356
344
  } from '@abi-software/map-utilities';
357
345
  import '@abi-software/map-utilities/dist/style.css';
346
+ import {
347
+ capitalise,
348
+ formatAlertText as formatAlertTextUtil,
349
+ scrollToRef,
350
+ } from '../utils/common.js';
358
351
 
359
352
  const titleCase = (str) => {
360
353
  return str.replace(/\w\S*/g, (t) => {
361
- return t.charAt(0).toUpperCase() + t.substr(1).toLowerCase()
362
- })
363
- }
364
-
365
- const capitalise = function (str) {
366
- if (str) return str.charAt(0).toUpperCase() + str.slice(1)
367
- return ''
368
- }
354
+ return t.charAt(0).toUpperCase() + t.substr(1).toLowerCase();
355
+ });
356
+ };
369
357
 
370
358
  export default {
371
359
  name: 'ConnectivityInfo',
372
360
  components: {
373
- Button,
374
- Container,
375
- Icon,
376
361
  ElIconWarning,
377
362
  ElIconLocation,
378
363
  ElIconSearch,
@@ -388,7 +373,7 @@ export default {
388
373
  props: {
389
374
  connectivityEntry: {
390
375
  type: Array,
391
- default: [],
376
+ default: () => [],
392
377
  },
393
378
  entryData: {
394
379
  type: Object,
@@ -396,7 +381,7 @@ export default {
396
381
  },
397
382
  entryId: {
398
383
  type: String,
399
- default: "",
384
+ default: '',
400
385
  },
401
386
  envVars: {
402
387
  type: Object,
@@ -444,18 +429,15 @@ export default {
444
429
  return this.entry?.title || '';
445
430
  },
446
431
  hasProvenanceTaxonomyLabel: function () {
447
- return (
448
- this.entry.provenanceTaxonomyLabel &&
449
- this.entry.provenanceTaxonomyLabel.length > 0
450
- );
432
+ return this.entry.provenanceTaxonomyLabel && this.entry.provenanceTaxonomyLabel.length > 0;
451
433
  },
452
434
  provSpeciesDescription: function () {
453
- let text = "Studied in";
435
+ let text = 'Studied in';
454
436
  this.entry.provenanceTaxonomyLabel.forEach((label) => {
455
437
  text += ` ${label},`;
456
438
  });
457
439
  text = text.slice(0, -1); // remove last comma
458
- text += " species";
440
+ text += ' species';
459
441
  return text;
460
442
  },
461
443
  connectivityKey: function () {
@@ -517,9 +499,7 @@ export default {
517
499
  handler: function (newVal, oldVal) {
518
500
  if (newVal && newVal !== oldVal) {
519
501
  this.connectivityLoading = true;
520
- this.activeView =
521
- localStorage.getItem('connectivity-active-view') ||
522
- this.activeView;
502
+ this.activeView = localStorage.getItem('connectivity-active-view') || this.activeView;
523
503
  if (this.activeView === 'graphView') {
524
504
  this.graphViewLoaded = true;
525
505
  }
@@ -544,10 +524,10 @@ export default {
544
524
  },
545
525
  methods: {
546
526
  titleCase: function (title) {
547
- return titleCase(title)
527
+ return titleCase(title);
548
528
  },
549
529
  capitalise: function (text) {
550
- return capitalise(text)
530
+ return capitalise(text);
551
531
  },
552
532
  toggleTitleExpansion: function () {
553
533
  this.isTitleExpanded = !this.isTitleExpanded;
@@ -589,16 +569,16 @@ export default {
589
569
  this.$emit('show-connectivity', featureIds);
590
570
 
591
571
  EventBus.emit('trackEvent', {
592
- 'event_name': `portal_maps_show_connectivity_on_map`,
593
- 'category': this.entry.id || '',
594
- 'location': 'map_sidebar_connectivity',
572
+ event_name: `portal_maps_show_connectivity_on_map`,
573
+ category: this.entry.id || '',
574
+ location: 'map_sidebar_connectivity',
595
575
  });
596
576
  },
597
577
  onCopied: function () {
598
578
  EventBus.emit('trackEvent', {
599
- 'event_name': `portal_maps_connectivity_copy`,
600
- 'category': this.entry.id || '',
601
- 'location': 'map_sidebar_connectivity',
579
+ event_name: `portal_maps_connectivity_copy`,
580
+ category: this.entry.id || '',
581
+ location: 'map_sidebar_connectivity',
602
582
  });
603
583
  },
604
584
  switchConnectivityView: function (val) {
@@ -613,9 +593,9 @@ export default {
613
593
  }
614
594
 
615
595
  EventBus.emit('trackEvent', {
616
- 'event_name': `portal_maps_connectivity_switch_view`,
617
- 'category': val,
618
- 'location': 'map_sidebar_connectivity',
596
+ event_name: `portal_maps_connectivity_switch_view`,
597
+ category: val,
598
+ location: 'map_sidebar_connectivity',
619
599
  });
620
600
  },
621
601
  openGraphInViewer: function () {
@@ -647,7 +627,7 @@ export default {
647
627
  },
648
628
  onTapNode: function (data) {
649
629
  // save selected state for list view
650
- const name = data.map(t => t.label).join(', ');
630
+ const name = data.map((t) => t.label).join(', ');
651
631
  this.onConnectivityHovered(name);
652
632
  },
653
633
  onShowReferenceConnectivities: function (refSource) {
@@ -716,9 +696,7 @@ export default {
716
696
  });
717
697
  transformedItems.push(itemNames.join(','));
718
698
  });
719
- const contentList = transformedItems
720
- .map((item) => `<li>${item}</li>`)
721
- .join('\n');
699
+ const contentList = transformedItems.map((item) => `<li>${item}</li>`).join('\n');
722
700
  contentString += '\n';
723
701
  contentString += `<ul>${contentList}</ul>`;
724
702
  return contentString;
@@ -734,7 +712,7 @@ export default {
734
712
  const getFirstId = (idArr) => {
735
713
  if (!idArr?.length) return null;
736
714
  const first = idArr[0];
737
- return typeof first === 'string' ? first : (first?.[0] || null);
715
+ return typeof first === 'string' ? first : first?.[0] || null;
738
716
  };
739
717
  const transformedItems = sortedCombinations.map((item) => {
740
718
  const isDirectMatch =
@@ -764,9 +742,7 @@ export default {
764
742
  hasDifferReference = true;
765
743
  return `<s>${sckanLabelWithId}</s> (<strong>Map:</strong> ${mapLabelWithId}) **`;
766
744
  });
767
- const contentList = transformedItems
768
- .map((item) => `<li>${item}</li>`)
769
- .join('\n');
745
+ const contentList = transformedItems.map((item) => `<li>${item}</li>`).join('\n');
770
746
  contentString += '\n';
771
747
  contentString += `<ul>${contentList}</ul>`;
772
748
  return contentString;
@@ -776,7 +752,7 @@ export default {
776
752
  if (this.entry['nerve-label']?.length) {
777
753
  const title = 'Nerves';
778
754
  const nerves = this.entry['nerve-label'];
779
- const nerveLabels = nerves.map(nerve => Object.values(nerve)).flat(Infinity);
755
+ const nerveLabels = nerves.map((nerve) => Object.values(nerve)).flat(Infinity);
780
756
  const transformedNerves = transformData(title, nerveLabels);
781
757
  contentArray.push(transformedNerves);
782
758
  }
@@ -784,17 +760,26 @@ export default {
784
760
  // Origins / Components / Destination
785
761
  if (this.hasSingleConnectivityList) {
786
762
  if (this.originsCombinations?.length) {
787
- const transformedOrigins = transformReconciliationData('Origin', this.originsCombinations);
763
+ const transformedOrigins = transformReconciliationData(
764
+ 'Origin',
765
+ this.originsCombinations,
766
+ );
788
767
  contentArray.push(transformedOrigins);
789
768
  }
790
769
 
791
770
  if (this.componentsCombinations?.length) {
792
- const transformedComponents = transformReconciliationData('Components', this.componentsCombinations);
771
+ const transformedComponents = transformReconciliationData(
772
+ 'Components',
773
+ this.componentsCombinations,
774
+ );
793
775
  contentArray.push(transformedComponents);
794
776
  }
795
777
 
796
778
  if (this.destinationsCombinations?.length) {
797
- const transformedDestinations = transformReconciliationData('Destination', this.destinationsCombinations);
779
+ const transformedDestinations = transformReconciliationData(
780
+ 'Destination',
781
+ this.destinationsCombinations,
782
+ );
798
783
  contentArray.push(transformedDestinations);
799
784
  }
800
785
 
@@ -810,17 +795,29 @@ export default {
810
795
  }
811
796
  } else {
812
797
  if (this.origins?.length) {
813
- const transformedOrigins = transformData('Origin', this.origins, this.originsWithDatasets);
798
+ const transformedOrigins = transformData(
799
+ 'Origin',
800
+ this.origins,
801
+ this.originsWithDatasets,
802
+ );
814
803
  contentArray.push(transformedOrigins);
815
804
  }
816
805
 
817
806
  if (this.components?.length) {
818
- const transformedComponents = transformData('Components', this.components, this.componentsWithDatasets);
807
+ const transformedComponents = transformData(
808
+ 'Components',
809
+ this.components,
810
+ this.componentsWithDatasets,
811
+ );
819
812
  contentArray.push(transformedComponents);
820
813
  }
821
814
 
822
815
  if (this.destinations?.length) {
823
- const transformedDestinations = transformData('Destination', this.destinations, this.destinationsWithDatasets);
816
+ const transformedDestinations = transformData(
817
+ 'Destination',
818
+ this.destinations,
819
+ this.destinationsWithDatasets,
820
+ );
824
821
  contentArray.push(transformedDestinations);
825
822
  }
826
823
  }
@@ -829,9 +826,7 @@ export default {
829
826
  if (references) {
830
827
  let contentString = `<div><strong>References</strong></div>`;
831
828
  contentString += '\n';
832
- const contentList = references.list
833
- .map((item) => `<li>${item}</li>`)
834
- .join('\n');
829
+ const contentList = references.list.map((item) => `<li>${item}</li>`).join('\n');
835
830
  contentString += `<ul>${contentList}</ul>`;
836
831
  contentArray.push(contentString);
837
832
  }
@@ -846,19 +841,24 @@ export default {
846
841
  const fields = [`<div><strong>${consultant.name}</strong></div>`];
847
842
 
848
843
  if (consultant.orcidId) {
849
- fields.push(`<div>`)
850
- fields.push(`<strong>ORCID iD</strong>: <span>${consultant.orcidId}</span> `)
851
- fields.push(`(<a href="${consultant.url}" target="_blank" rel="noopener noreferrer">${consultant.url}</a>)`)
844
+ fields.push(`<div>`);
845
+ fields.push(`<strong>ORCID iD</strong>: <span>${consultant.orcidId}</span> `);
846
+ fields.push(
847
+ `(<a href="${consultant.url}" target="_blank" rel="noopener noreferrer">${consultant.url}</a>)`,
848
+ );
852
849
  fields.push(`</div>`);
853
850
  }
854
851
 
855
- const rrid = consultant.url.indexOf('RRID:') > -1
856
- ? 'RRID:' + consultant.url.split('RRID:')[1]
857
- : '';
852
+ const rrid =
853
+ consultant.url.indexOf('RRID:') > -1
854
+ ? 'RRID:' + consultant.url.split('RRID:')[1]
855
+ : '';
858
856
  if (rrid) {
859
- fields.push(`<div>`)
860
- fields.push(`<strong>RRID</strong>: <span>${rrid}</span> `)
861
- fields.push(`(<a href="${consultant.url}" target="_blank" rel="noopener noreferrer">${consultant.url}</a>)`)
857
+ fields.push(`<div>`);
858
+ fields.push(`<strong>RRID</strong>: <span>${rrid}</span> `);
859
+ fields.push(
860
+ `(<a href="${consultant.url}" target="_blank" rel="noopener noreferrer">${consultant.url}</a>)`,
861
+ );
862
862
  fields.push(`</div>`);
863
863
  }
864
864
 
@@ -896,17 +896,17 @@ export default {
896
896
  const names = label.split(','); // some features have more than one value
897
897
  let data = [];
898
898
  names.forEach((n) => {
899
- const foundData = allWithDatasets.find((a) =>
900
- a.name.toLowerCase().trim() === n.toLowerCase().trim()
899
+ const foundData = allWithDatasets.find(
900
+ (a) => a.name.toLowerCase().trim() === n.toLowerCase().trim(),
901
901
  );
902
902
  if (foundData) {
903
903
  data.push({
904
904
  id: foundData.id,
905
- label: foundData.name
905
+ label: foundData.name,
906
906
  });
907
907
  }
908
908
  });
909
- return data
909
+ return data;
910
910
  },
911
911
  fetchExpertConsultants: async function () {
912
912
  this.expertConsultants = this.expertConsultantURLs.map((url) => ({
@@ -935,6 +935,9 @@ export default {
935
935
  return null;
936
936
  }
937
937
 
938
+ //A scicrunch entry typically looks like https://scicrunch.org/resolver/RRID:XXXXXX
939
+ //but due to CORS issue, we need to replace it with sparc-api interface,
940
+ //Replacing the domain while leaving the subpath the same.
938
941
  const APIURL = isScicrunchURL
939
942
  ? url.replace(scicrunchBase, `${apiLocationBase}scicrunch`)
940
943
  : url.replace(orcidBase, orcidAPIBase);
@@ -1012,7 +1015,8 @@ export default {
1012
1015
  }
1013
1016
 
1014
1017
  const orcidId = data?.['orcid-identifier']?.path || '';
1015
- const employmentSummary = data?.['activities-summary']?.['employments']?.['employment-summary'] || [];
1018
+ const employmentSummary =
1019
+ data?.['activities-summary']?.['employments']?.['employment-summary'] || [];
1016
1020
  const latestEmployment = employmentSummary[0] || {};
1017
1021
 
1018
1022
  this.updateExpertConsultantByURL(url, {
@@ -1039,7 +1043,9 @@ export default {
1039
1043
  }
1040
1044
  },
1041
1045
  updateExpertConsultantByURL: function (url, fields = {}) {
1042
- const consultantIndex = this.expertConsultants.findIndex((consultant) => consultant.url === url);
1046
+ const consultantIndex = this.expertConsultants.findIndex(
1047
+ (consultant) => consultant.url === url,
1048
+ );
1043
1049
  if (consultantIndex === -1) {
1044
1050
  return;
1045
1051
  }
@@ -1099,13 +1105,13 @@ export default {
1099
1105
  });
1100
1106
 
1101
1107
  EventBus.emit('trackEvent', {
1102
- 'event_name': `portal_maps_connectivity_source_change`,
1103
- 'category': connectivitySource,
1104
- 'location': 'map_sidebar_connectivity',
1108
+ event_name: `portal_maps_connectivity_source_change`,
1109
+ category: connectivitySource,
1110
+ location: 'map_sidebar_connectivity',
1105
1111
  });
1106
1112
  },
1107
1113
  updateGraphConnectivity: function () {
1108
- if (this.connectivitySource === "map") {
1114
+ if (this.connectivitySource === 'map') {
1109
1115
  this.getConnectionsFromMap().then((response) => {
1110
1116
  // show sckan source graph if map source not exist
1111
1117
  this.connectivityFromMap = null;
@@ -1122,8 +1128,7 @@ export default {
1122
1128
  getConnectionsFromMap: async function () {
1123
1129
  if (this.entry.mapuuid) {
1124
1130
  const url =
1125
- this.flatmapApi +
1126
- `flatmap/${this.entry.mapuuid}/connectivity/${this.entry.featureId[0]}`;
1131
+ this.flatmapApi + `flatmap/${this.entry.mapuuid}/connectivity/${this.entry.featureId[0]}`;
1127
1132
 
1128
1133
  try {
1129
1134
  const response = await fetch(url);
@@ -1135,9 +1140,9 @@ export default {
1135
1140
  } catch (error) {
1136
1141
  EventBus.emit('connectivity-source-change', {
1137
1142
  entry: this.entry,
1138
- connectivitySource: "sckan",
1143
+ connectivitySource: 'sckan',
1139
1144
  });
1140
- throw new Error(error);
1145
+ throw error;
1141
1146
  }
1142
1147
  }
1143
1148
  },
@@ -1148,58 +1153,19 @@ export default {
1148
1153
  this.$emit('close-connectivity');
1149
1154
 
1150
1155
  EventBus.emit('trackEvent', {
1151
- 'event_name': `portal_maps_connectivity_close`,
1152
- 'category': this.entry.id || '',
1153
- 'location': 'map_sidebar_connectivity',
1156
+ event_name: `portal_maps_connectivity_close`,
1157
+ category: this.entry.id || '',
1158
+ location: 'map_sidebar_connectivity',
1154
1159
  });
1155
1160
  },
1156
1161
  onTrackEvent: function (data) {
1157
1162
  EventBus.emit('trackEvent', data);
1158
1163
  },
1159
1164
  showAlertMessage: function () {
1160
- // scroll to alert message
1161
- this.$nextTick(() => {
1162
- const alertElement = this.$refs.alertElement;
1163
- if (alertElement) {
1164
- alertElement.scrollIntoView({
1165
- behavior: 'smooth',
1166
- block: 'start',
1167
- inline: 'nearest',
1168
- });
1169
- }
1170
- });
1165
+ scrollToRef(this, 'alertElement');
1171
1166
  },
1172
1167
  formatAlertText: function (text) {
1173
- if (!text) return '';
1174
- const escaped = text
1175
- .replace(/&/g, '&amp;')
1176
- .replace(/</g, '&lt;')
1177
- .replace(/>/g, '&gt;');
1178
- const linkified = escaped.replace(
1179
- /(https?:\/\/[^\s"<>\[]+)/g,
1180
- (url) => {
1181
- const parts = url.match(/^(.*?)([\].,;:!?]*)$/);
1182
- const cleanUrl = parts ? parts[1] : url;
1183
- const suffix = parts ? parts[2] : '';
1184
- return `<a href="${cleanUrl}" target="_blank" rel="noopener noreferrer">${cleanUrl}</a>${suffix}`;
1185
- }
1186
- );
1187
-
1188
- const normalised = linkified
1189
- .replace(/\\n/g, '\n')
1190
- .replace(/\r\n/g, '\n')
1191
- .replace(/\r/g, '\n');
1192
-
1193
- return normalised
1194
- .split('\n')
1195
- .map((line) => {
1196
- const withBoldLabel = line.replace(
1197
- /^\s*([A-Za-z][^:<]{0,120}:)/,
1198
- '<strong>$1</strong>'
1199
- );
1200
- return `<div class="alert-line">${withBoldLabel}</div>`;
1201
- })
1202
- .join('\n');
1168
+ return formatAlertTextUtil(text, { formatLines: true });
1203
1169
  },
1204
1170
  },
1205
1171
  mounted: function () {
@@ -1212,7 +1178,7 @@ export default {
1212
1178
  this.connectivityError = { ...connectivityError };
1213
1179
  });
1214
1180
  },
1215
- }
1181
+ };
1216
1182
  </script>
1217
1183
 
1218
1184
  <style lang="scss" scoped>
@@ -1335,10 +1301,14 @@ export default {
1335
1301
  }
1336
1302
 
1337
1303
  .slide-fade-enter-active {
1338
- transition: opacity 0.5s, transform 0.5s;
1304
+ transition:
1305
+ opacity 0.5s,
1306
+ transform 0.5s;
1339
1307
  }
1340
1308
  .slide-fade-leave-active {
1341
- transition: opacity 0.2s, transform 0.2s;
1309
+ transition:
1310
+ opacity 0.2s,
1311
+ transform 0.2s;
1342
1312
  }
1343
1313
  .slide-fade-enter, .slide-fade-leave-to /* .slide-fade-leave-active in <2.1.8 */ {
1344
1314
  opacity: 0;
@@ -1737,7 +1707,7 @@ export default {
1737
1707
 
1738
1708
  + .attribute-content {
1739
1709
  &::before {
1740
- content: "";
1710
+ content: '';
1741
1711
  width: 90%;
1742
1712
  height: 1px;
1743
1713
  background-color: var(--el-border-color);
@@ -1795,7 +1765,7 @@ export default {
1795
1765
  }
1796
1766
 
1797
1767
  &::after {
1798
- content: "";
1768
+ content: '';
1799
1769
  display: block;
1800
1770
  width: 100%;
1801
1771
  height: 100%;
@@ -1807,7 +1777,8 @@ export default {
1807
1777
  animation-iteration-count: infinite;
1808
1778
  animation-name: loadingAnimation;
1809
1779
  animation-timing-function: linear;
1810
- background: linear-gradient(to right,
1780
+ background: linear-gradient(
1781
+ to right,
1811
1782
  var(--el-bg-color-page) 5%,
1812
1783
  var(--el-color-info-light-8) 15%,
1813
1784
  var(--el-bg-color-page) 30%