@abi-software/map-side-bar 2.14.1-simulation.8 → 2.14.2-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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abi-software/map-side-bar",
3
- "version": "2.14.1-simulation.8",
3
+ "version": "2.14.2-demo.0",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
package/src/App.vue CHANGED
@@ -19,7 +19,6 @@
19
19
  <el-button @click="getFacets">Get facets</el-button>
20
20
  <el-button @click="toggleCreateData">Create Data/Annotation</el-button>
21
21
  <el-button @click="openConnectivitySearch()">Connectivity Search</el-button>
22
- <el-button @click="displayFileInfo()">Display file info</el-button>
23
22
  </div>
24
23
  <SideBar
25
24
  :envVars="envVars"
@@ -136,7 +135,6 @@ export default {
136
135
  PENNSIEVE_API_LOCATION: import.meta.env.VITE_APP_PENNSIEVE_API_LOCATION,
137
136
  BL_SERVER_URL: import.meta.env.VITE_APP_BL_SERVER_URL,
138
137
  ROOT_URL: import.meta.env.VITE_APP_ROOT_URL,
139
- TEST_DATA_LOCATION: import.meta.env.VITE_APP_TEST_DATA_LOCATION,
140
138
  FLATMAPAPI_LOCATION: import.meta.env.VITE_FLATMAPAPI_LOCATION,
141
139
  },
142
140
  connectivityEntry: [],
@@ -368,10 +366,6 @@ export default {
368
366
  },
369
367
  onConnectivityCollapseChange: function () {
370
368
  this.connectivityEntry = [...exampleConnectivityInput]
371
- },
372
- displayFileInfo: function() {
373
- this.$refs.sideBar.displayFileInfo(1024, "csv", "reveal")
374
-
375
369
  }
376
370
  },
377
371
  mounted: async function () {
@@ -1,6 +1,6 @@
1
1
  <template>
2
- <div v-if="visible" class="container" ref="container">
3
- <div v-if="displayText">View data types:</div>
2
+ <div v-if="categories['All'].size > 1" class="container" ref="container">
3
+ <div>View data types:</div>
4
4
  <template v-for="(item, key) in categories">
5
5
  <el-button
6
6
  v-if="item.size > 0"
@@ -32,15 +32,7 @@ export default {
32
32
  return []
33
33
  },
34
34
  },
35
- displayDataset: {
36
- type: Boolean,
37
- default: true,
38
- },
39
- displayText: {
40
- type: Boolean,
41
- default: true,
42
- },
43
- items: {
35
+ entry: {
44
36
  type: Object,
45
37
  default: () => {
46
38
  return {}
@@ -50,24 +42,22 @@ export default {
50
42
  data: function () {
51
43
  return {
52
44
  //Always start with 1 image - the dataset thumbnail itself
53
- categories: { },
45
+ categories: { All: { size: 1 }, Dataset: { size: 1 } },
54
46
  active: 'All',
55
- totalSize: 0,
56
- }
57
- },
58
- computed: {
59
- // This computed property populates filter data's entry object with $data from this sidebar
60
- visible: function () {
61
- return (this.displayDataset && this.totalSize > 1) ||
62
- (!this.displayDataset && this.totalSize > 0)
63
47
  }
64
48
  },
65
49
  methods: {
66
- addToCategories: function (name) {
67
- const array = this.items[name]
50
+ addToCategories: function (array, name) {
68
51
  if (array && array.length > 0) {
69
52
  this.categories[name] = { size: array.length }
70
- this.totalSize += array.length
53
+ this.categories['All'].size += array.length
54
+ }
55
+ },
56
+ addSimulationsToCategories: function (array) {
57
+ if (array && array.length > 0) {
58
+ const size = array.length
59
+ this.categories['Simulations'] = { size }
60
+ this.categories['All'].size += size
71
61
  }
72
62
  },
73
63
  categoryClicked: function (name) {
@@ -76,34 +66,14 @@ export default {
76
66
  },
77
67
  },
78
68
  watch: {
79
- items: {
69
+ entry: {
80
70
  deep: true,
81
71
  immediate: true,
82
72
  handler: function () {
83
- this.categories = {}
84
- this.totalSize = 0
85
- this.active = "All"
86
- let keys = ['Flatmaps', 'Plots', 'Protocol Data', 'Scaffolds', 'Simulations']
87
- keys.forEach(key => this.addToCategories(key))
88
- if (this.displayDataset) {
89
- this.totalSize += 1
90
- this.categories.All = { size: this.totalSize }
91
- this.categories.Dataset = { size: 1 }
92
- } else {
93
- const keys = Object.keys(this.categories)
94
- if (keys.length > 1) {
95
- this.categories.All = { size: this.totalSize }
96
- } else if (keys.length === 1) {
97
- this.categoryClicked(keys[0])
98
- }
99
- }
100
- this.categories = Object.keys(this.categories).sort().reduce(
101
- (obj, key) => {
102
- obj[key] = this.categories[key];
103
- return obj;
104
- },
105
- {}
106
- );
73
+ this.addToCategories(this.entry.flatmaps, 'Flatmaps')
74
+ this.addToCategories(this.entry.plots, 'Plots')
75
+ this.addToCategories(this.entry.scaffolds, 'Scaffolds')
76
+ this.addSimulationsToCategories(this.entry.simulation)
107
77
  /** disable the following
108
78
  this.addToCategories(this.entry.images, 'Images');
109
79
  this.addToCategories(this.entry.videos, 'Videos');
@@ -12,21 +12,6 @@
12
12
  @click="toggleTitleExpansion"
13
13
  >
14
14
  <span>{{ capitalise(displayTitle) }}</span>
15
- <template v-if="entry.featuresAlert">
16
- <el-popover
17
- width="250"
18
- trigger="hover"
19
- :teleported="false"
20
- popper-class="popover-origin-help"
21
- >
22
- <template #reference>
23
- <el-icon class="alert"><el-icon-warn-triangle-filled /></el-icon>
24
- </template>
25
- <span style="word-break: keep-all">
26
- {{ entry.featuresAlert }}
27
- </span>
28
- </el-popover>
29
- </template>
30
15
  </div>
31
16
  <button
32
17
  v-if="showTitleToggle"
@@ -41,7 +26,19 @@
41
26
  </el-icon>
42
27
  </button>
43
28
  </div>
44
- <div class="subtitle"><strong>Id: </strong>{{ entry.featureId[0] }}</div>
29
+ <div class="subtitle">
30
+ <strong>Id: </strong>{{ entry.featureId[0] }}
31
+ <el-button
32
+ round
33
+ size="small"
34
+ class="alert-chip"
35
+ @click="showAlertMessage"
36
+ v-if="entry.featuresAlert"
37
+ >
38
+ <el-icon class="alert"><el-icon-warn-triangle-filled /></el-icon>
39
+ Notes
40
+ </el-button>
41
+ </div>
45
42
  <div v-if="hasProvenanceTaxonomyLabel" class="subtitle">
46
43
  {{ provSpeciesDescription }}
47
44
  </div>
@@ -290,6 +287,22 @@
290
287
  @trackEvent="onTrackEvent"
291
288
  />
292
289
  </div>
290
+
291
+ <div
292
+ ref="alertElement"
293
+ class="content-container content-container-alert"
294
+ v-if="entry.featuresAlert"
295
+ >
296
+ <div class="block attribute-title-container">
297
+ <span class="attribute-title">Alert</span>
298
+ </div>
299
+ <div class="block">
300
+ <div class="alert-block"
301
+ v-for="alert in entry.featuresAlert"
302
+ v-html="formatAlertText(alert)"
303
+ ></div>
304
+ </div>
305
+ </div>
293
306
  </div>
294
307
  </template>
295
308
 
@@ -784,6 +797,14 @@ export default {
784
797
  contentArray.push(contentString);
785
798
  }
786
799
 
800
+ // Alert
801
+ if (this.entry.featuresAlert) {
802
+ const alertContent = this.entry.featuresAlert
803
+ .map((alert) => this.formatAlertText(alert))
804
+ .join('\n');
805
+ contentArray.push(`<div><strong>Alert</strong></div>\n${alertContent}`);
806
+ }
807
+
787
808
  return contentArray.join('\n\n<br>');
788
809
  },
789
810
  getConnectivityDatasets: function (label) {
@@ -910,6 +931,51 @@ export default {
910
931
  onTrackEvent: function (data) {
911
932
  EventBus.emit('trackEvent', data);
912
933
  },
934
+ showAlertMessage: function () {
935
+ // scroll to alert message
936
+ this.$nextTick(() => {
937
+ const alertElement = this.$refs.alertElement;
938
+ if (alertElement) {
939
+ alertElement.scrollIntoView({
940
+ behavior: 'smooth',
941
+ block: 'start',
942
+ inline: 'nearest',
943
+ });
944
+ }
945
+ });
946
+ },
947
+ formatAlertText: function (text) {
948
+ if (!text) return '';
949
+ const escaped = text
950
+ .replace(/&/g, '&amp;')
951
+ .replace(/</g, '&lt;')
952
+ .replace(/>/g, '&gt;');
953
+ const linkified = escaped.replace(
954
+ /(https?:\/\/[^\s"<>\[]+)/g,
955
+ (url) => {
956
+ const parts = url.match(/^(.*?)([\].,;:!?]*)$/);
957
+ const cleanUrl = parts ? parts[1] : url;
958
+ const suffix = parts ? parts[2] : '';
959
+ return `<a href="${cleanUrl}" target="_blank" rel="noopener noreferrer">${cleanUrl}</a>${suffix}`;
960
+ }
961
+ );
962
+
963
+ const normalised = linkified
964
+ .replace(/\\n/g, '\n')
965
+ .replace(/\r\n/g, '\n')
966
+ .replace(/\r/g, '\n');
967
+
968
+ return normalised
969
+ .split('\n')
970
+ .map((line) => {
971
+ const withBoldLabel = line.replace(
972
+ /^\s*([A-Za-z][^:<]{0,120}:)/,
973
+ '<strong>$1</strong>'
974
+ );
975
+ return `<div class="alert-line">${withBoldLabel}</div>`;
976
+ })
977
+ .join('\n');
978
+ },
913
979
  },
914
980
  mounted: function () {
915
981
  this.updatedCopyContent = this.getUpdateCopyContent();
@@ -1088,15 +1154,6 @@ export default {
1088
1154
  text-transform: uppercase;
1089
1155
  }
1090
1156
 
1091
- .main {
1092
- .el-button.is-round {
1093
- border-radius: 4px;
1094
- padding: 9px 20px 10px 20px;
1095
- display: flex;
1096
- height: 36px;
1097
- }
1098
- }
1099
-
1100
1157
  .button {
1101
1158
  margin-left: 0px !important;
1102
1159
  margin-top: 0px !important;
@@ -1419,10 +1476,6 @@ export default {
1419
1476
 
1420
1477
  .content-container-connectivity {
1421
1478
  position: relative;
1422
-
1423
- &:not([style*="display: none"]) ~ .content-container-references {
1424
- margin-top: -1.25rem;
1425
- }
1426
1479
  }
1427
1480
 
1428
1481
  .attribute-content {
@@ -1466,4 +1519,48 @@ export default {
1466
1519
  margin-bottom: 0.5em;
1467
1520
  }
1468
1521
  }
1522
+
1523
+ .alert-block {
1524
+ background-color: var(--el-color-warning-light-9);
1525
+ border: 1px dashed var(--el-color-warning);
1526
+ padding: 0.75rem;
1527
+ border-radius: 4px;
1528
+
1529
+ :deep(.alert-line + .alert-line) {
1530
+ margin-top: 0.5rem;
1531
+ }
1532
+
1533
+ :deep(a) {
1534
+ color: $app-primary-color;
1535
+ word-break: break-all;
1536
+
1537
+ &:hover {
1538
+ opacity: 0.8;
1539
+ }
1540
+ }
1541
+ }
1542
+
1543
+ .alert-chip {
1544
+ margin-left: 5px;
1545
+ background-color: $app-primary-color;
1546
+ border-color: $app-primary-color;
1547
+ color: #fff;
1548
+
1549
+ &:hover {
1550
+ color: #fff !important;
1551
+ background-color: #ac76c5 !important;
1552
+ border: 1px solid #ac76c5 !important;
1553
+ }
1554
+
1555
+ :deep(> span) {
1556
+ gap: 2px;
1557
+ }
1558
+
1559
+ .alert {
1560
+ width: 1rem;
1561
+ height: 1rem;
1562
+ color: inherit;
1563
+ margin: 0;
1564
+ }
1565
+ }
1469
1566
  </style>