@abi-software/map-side-bar 2.5.0-beta.3 → 2.5.0-beta.4

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.5.0-beta.3",
3
+ "version": "2.5.0-beta.4",
4
4
  "files": [
5
5
  "dist/*",
6
6
  "src/*",
@@ -39,7 +39,7 @@
39
39
  },
40
40
  "dependencies": {
41
41
  "@abi-software/gallery": "^1.1.2",
42
- "@abi-software/map-utilities": "^1.2.0-beta.8",
42
+ "@abi-software/map-utilities": "^1.2.1-beta.0",
43
43
  "@abi-software/svg-sprite": "^1.0.1",
44
44
  "@element-plus/icons-vue": "^2.3.1",
45
45
  "algoliasearch": "^4.10.5",
package/src/App.vue CHANGED
@@ -29,6 +29,7 @@
29
29
  @tabClicked="tabClicked"
30
30
  @search-changed="searchChanged($event)"
31
31
  @hover-changed="hoverChanged($event)"
32
+ @connectivity-component-click="onConnectivityComponentClick"
32
33
  @actionClick="action"
33
34
  />
34
35
  </div>
@@ -123,6 +124,7 @@ export default {
123
124
  BL_SERVER_URL: import.meta.env.VITE_APP_BL_SERVER_URL,
124
125
  NL_LINK_PREFIX: import.meta.env.VITE_APP_NL_LINK_PREFIX,
125
126
  ROOT_URL: import.meta.env.VITE_APP_ROOT_URL,
127
+ FLATMAPAPI_LOCATION: import.meta.env.VITE_FLATMAPAPI_LOCATION,
126
128
  },
127
129
  connectivityInput: exampleConnectivityInput,
128
130
  activeId: 1,
@@ -252,6 +254,9 @@ export default {
252
254
  } else {
253
255
  this.createData = null
254
256
  }
257
+ },
258
+ onConnectivityComponentClick: function(data) {
259
+ console.log("onConnectivityComponentClick" , data)
255
260
  }
256
261
  },
257
262
  mounted: function () {
@@ -35,7 +35,9 @@
35
35
  <div class="block" v-else>
36
36
  <div class="title">{{ entry.featureId }}</div>
37
37
  </div>
38
- <external-resource-card :resources="resources"></external-resource-card>
38
+ <div class="block" v-if="resources.length">
39
+ <external-resource-card :resources="resources"></external-resource-card>
40
+ </div>
39
41
  </div>
40
42
  <div class="title-buttons">
41
43
  <el-popover
@@ -58,7 +60,28 @@
58
60
  <CopyToClipboard :content="updatedCopyContent" />
59
61
  </div>
60
62
  </div>
61
- <div class="content-container scrollbar">
63
+
64
+ <div class="content-container population-display">
65
+ <div class="block attribute-title-container">
66
+ <span class="attribute-title">Population Display</span>
67
+ </div>
68
+ <div class="block buttons-row">
69
+ <el-button
70
+ :class="activeView === 'listView' ? 'button' : 'el-button-secondary'"
71
+ @click="switchConnectivityView('listView')"
72
+ >
73
+ List view
74
+ </el-button>
75
+ <el-button
76
+ :class="activeView === 'graphView' ? 'button' : 'el-button-secondary'"
77
+ @click="switchConnectivityView('graphView')"
78
+ >
79
+ Graph view
80
+ </el-button>
81
+ </div>
82
+ </div>
83
+
84
+ <div class="content-container" v-if="activeView === 'listView'">
62
85
  {{ entry.paths }}
63
86
  <div v-if="entry.origins && entry.origins.length > 0" class="block">
64
87
  <div class="attribute-title-container">
@@ -81,11 +104,14 @@
81
104
  <div
82
105
  v-for="(origin, i) in entry.origins"
83
106
  class="attribute-content"
107
+ :class="{'active': origin === selectedConnectivity}"
84
108
  :origin-item-label="origin"
85
109
  :key="origin"
110
+ @mouseenter="toggleConnectivityTooltip(origin, true)"
111
+ @mouseleave="toggleConnectivityTooltip(origin, false)"
112
+ @click="selectConnectivity(origin)"
86
113
  >
87
114
  {{ capitalise(origin) }}
88
- <div v-if="i != entry.origins.length - 1" class="seperator"></div>
89
115
  </div>
90
116
  <el-button
91
117
  v-show="
@@ -109,14 +135,14 @@
109
135
  <div
110
136
  v-for="(component, i) in entry.components"
111
137
  class="attribute-content"
138
+ :class="{'active': component === selectedConnectivity}"
112
139
  :component-item-label="component"
113
140
  :key="component"
141
+ @mouseenter="toggleConnectivityTooltip(component, true)"
142
+ @mouseleave="toggleConnectivityTooltip(component, false)"
143
+ @click="selectConnectivity(component)"
114
144
  >
115
145
  {{ capitalise(component) }}
116
- <div
117
- v-if="i != entry.components.length - 1"
118
- class="seperator"
119
- ></div>
120
146
  </div>
121
147
  </div>
122
148
  <div
@@ -142,14 +168,14 @@
142
168
  <div
143
169
  v-for="(destination, i) in entry.destinations"
144
170
  class="attribute-content"
171
+ :class="{'active': destination === selectedConnectivity}"
145
172
  :destination-item-label="destination"
146
173
  :key="destination"
174
+ @mouseenter="toggleConnectivityTooltip(destination, true)"
175
+ @mouseleave="toggleConnectivityTooltip(destination, false)"
176
+ @click="selectConnectivity(destination)"
147
177
  >
148
178
  {{ capitalise(destination) }}
149
- <div
150
- v-if="i != entry.destinations.length - 1"
151
- class="seperator"
152
- ></div>
153
179
  </div>
154
180
  <el-button
155
181
  v-show="
@@ -163,18 +189,31 @@
163
189
  Explore destination data
164
190
  </el-button>
165
191
  </div>
166
-
167
- <el-button
192
+ <div
168
193
  v-show="
169
194
  entry.componentsWithDatasets &&
170
195
  entry.componentsWithDatasets.length > 0 &&
171
196
  shouldShowExploreButton(entry.componentsWithDatasets)
172
197
  "
173
- class="button"
174
- @click="openAll"
198
+ class="block"
175
199
  >
176
- Search for data on components
177
- </el-button>
200
+ <el-button
201
+ class="button"
202
+ @click="openAll"
203
+ >
204
+ Search for data on components
205
+ </el-button>
206
+ </div>
207
+ </div>
208
+
209
+ <div class="content-container" v-if="activeView === 'graphView'">
210
+ <connectivity-graph
211
+ :entry="entry.featureId[0]"
212
+ :mapServer="envVars.FLATMAPAPI_LOCATION"
213
+ :selectedConnectivityData="selectedConnectivityData"
214
+ @tap-node="onTapNode"
215
+ ref="connectivityGraphRef"
216
+ />
178
217
  </div>
179
218
  </div>
180
219
  </template>
@@ -193,7 +232,7 @@ import {
193
232
  } from 'element-plus'
194
233
  import ExternalResourceCard from './ExternalResourceCard.vue'
195
234
  import EventBus from './EventBus.js'
196
- import { CopyToClipboard } from '@abi-software/map-utilities';
235
+ import { CopyToClipboard, ConnectivityGraph } from '@abi-software/map-utilities';
197
236
  import '@abi-software/map-utilities/dist/style.css';
198
237
 
199
238
  const titleCase = (str) => {
@@ -218,6 +257,7 @@ export default {
218
257
  ElIconWarning,
219
258
  ExternalResourceCard,
220
259
  CopyToClipboard,
260
+ ConnectivityGraph,
221
261
  },
222
262
  props: {
223
263
  entry: {
@@ -233,6 +273,10 @@ export default {
233
273
  featuresAlert: undefined,
234
274
  }),
235
275
  },
276
+ envVars: {
277
+ type: Object,
278
+ default: () => {},
279
+ },
236
280
  availableAnatomyFacets: {
237
281
  type: Array,
238
282
  default: () => [],
@@ -244,6 +288,7 @@ export default {
244
288
  activeSpecies: undefined,
245
289
  pubmedSearchUrl: '',
246
290
  loading: false,
291
+ activeView: 'listView',
247
292
  facetList: [],
248
293
  showToolip: false,
249
294
  showDetails: false,
@@ -253,6 +298,8 @@ export default {
253
298
  },
254
299
  componentsWithDatasets: [],
255
300
  uberons: [{ id: undefined, name: undefined }],
301
+ selectedConnectivity: '',
302
+ selectedConnectivityData: [],
256
303
  }
257
304
  },
258
305
  watch: {
@@ -352,6 +399,29 @@ export default {
352
399
  // connected to flatmapvuer > moveMap(featureIds) function
353
400
  this.$emit('show-connectivity', featureIds);
354
401
  },
402
+ switchConnectivityView: function (val) {
403
+ this.activeView = val;
404
+
405
+ if (val === 'graphView') {
406
+ const connectivityGraphRef = this.$refs.connectivityGraphRef;
407
+ if (connectivityGraphRef && connectivityGraphRef.$el) {
408
+ connectivityGraphRef.$el.scrollIntoView({
409
+ behavior: 'smooth',
410
+ });
411
+ }
412
+ }
413
+ },
414
+ onTapNode: function (data) {
415
+ // save selected state for list view
416
+ const name = data.map(t => t.label).join(', ');
417
+ this.selectedConnectivity = name;
418
+ this.toggleConnectivityTooltip(name, true);
419
+
420
+ /**
421
+ * This event is triggered by connectivity-graph's `tap-node` event.
422
+ */
423
+ this.$emit('connectivity-component-click', data);
424
+ },
355
425
  getUpdateCopyContent: function () {
356
426
  if (!this.entry) {
357
427
  return '';
@@ -446,6 +516,58 @@ export default {
446
516
 
447
517
  return contentArray.join('\n\n<br>');
448
518
  },
519
+ toggleConnectivityTooltip: function (name, option) {
520
+ // if there has selected item
521
+ if (!option && this.selectedConnectivity) {
522
+ name = this.selectedConnectivity;
523
+ option = true;
524
+ }
525
+
526
+ const allWithDatasets = [
527
+ ...this.entry.componentsWithDatasets,
528
+ ...this.entry.destinationsWithDatasets,
529
+ ...this.entry.originsWithDatasets,
530
+ ];
531
+ const names = name.split(','); // some features have more than one value
532
+ const data = [];
533
+ if (option) {
534
+ names.forEach((n) => {
535
+ const foundData = allWithDatasets.find((a) =>
536
+ a.name.toLowerCase().trim() === n.toLowerCase().trim()
537
+ );
538
+
539
+ if (foundData) {
540
+ data.push({
541
+ id: foundData.id,
542
+ label: foundData.name
543
+ });
544
+ }
545
+ });
546
+ }
547
+
548
+ // saved state for graph view
549
+ this.selectedConnectivityData = data;
550
+ this.$emit('connectivity-component-click', data);
551
+ },
552
+ selectConnectivity: function (name) {
553
+ // clicking on the same item will unselect it
554
+ if (this.selectedConnectivity === name) {
555
+ this.selectedConnectivity = '';
556
+ this.toggleConnectivityTooltip(name, false);
557
+ } else {
558
+ this.selectedConnectivity = name;
559
+ this.toggleConnectivityTooltip(name, true);
560
+ }
561
+ },
562
+ },
563
+ mounted: function () {
564
+ EventBus.on('connectivity-graph-error', (errorInfo) => {
565
+ const connectivityGraphRef = this.$refs.connectivityGraphRef;
566
+
567
+ if (connectivityGraphRef) {
568
+ connectivityGraphRef.showErrorMessage(errorInfo);
569
+ }
570
+ });
449
571
  },
450
572
  }
451
573
  </script>
@@ -458,7 +580,7 @@ export default {
458
580
  }
459
581
 
460
582
  .connectivity-info-title {
461
- padding: 1rem;
583
+ padding: 0;
462
584
  display: flex;
463
585
  flex-direction: row;
464
586
  justify-content: space-between;
@@ -476,16 +598,8 @@ export default {
476
598
  color: $app-primary-color;
477
599
  }
478
600
 
479
- .block {
480
- margin-bottom: 0.5em;
481
-
482
- .main > &:first-of-type {
483
- margin-right: 1em;
484
- }
485
- }
486
-
487
- .pub {
488
- width: 16rem;
601
+ .block + .block {
602
+ margin-top: 0.5em;
489
603
  }
490
604
 
491
605
  .button-circle {
@@ -547,12 +661,6 @@ export default {
547
661
  }
548
662
  }
549
663
 
550
- .seperator {
551
- width: 90%;
552
- height: 1px;
553
- background-color: #bfbec2;
554
- }
555
-
556
664
  .hide {
557
665
  color: $app-primary-color;
558
666
  cursor: pointer;
@@ -585,6 +693,10 @@ export default {
585
693
  height: 100%;
586
694
  border-left: 1px solid var(--el-border-color);
587
695
  border-top: 1px solid var(--el-border-color);
696
+ display: flex;
697
+ flex-direction: column;
698
+ gap: 1.75rem;
699
+ padding: 1rem;
588
700
  }
589
701
 
590
702
  .attribute-title-container {
@@ -600,7 +712,39 @@ export default {
600
712
 
601
713
  .attribute-content {
602
714
  font-size: 14px;
603
- font-weight: 500;
715
+ transition: color 0.25s ease;
716
+ position: relative;
717
+ cursor: pointer;
718
+
719
+ &.active,
720
+ &:hover {
721
+ font-weight: 500;
722
+ color: $app-primary-color;
723
+ }
724
+
725
+ &.active {
726
+ font-weight: 600;
727
+
728
+ &::after {
729
+ content: "📌";
730
+ display: inline-block;
731
+ width: 1em;
732
+ font-size: 0.75em;
733
+ padding-left: 4px;
734
+ }
735
+ }
736
+
737
+ + .attribute-content {
738
+ &::before {
739
+ content: "";
740
+ width: 90%;
741
+ height: 1px;
742
+ background-color: var(--el-border-color);
743
+ position: absolute;
744
+ top: 0;
745
+ left: 0;
746
+ }
747
+ }
604
748
 
605
749
  &:last-of-type {
606
750
  margin-bottom: 0.5em;
@@ -627,16 +771,59 @@ export default {
627
771
  font-size: 14px !important;
628
772
  background-color: $app-primary-color;
629
773
  color: #fff;
774
+
775
+ &:hover {
776
+ color: #fff !important;
777
+ background-color: #ac76c5 !important;
778
+ border: 1px solid #ac76c5 !important;
779
+ }
780
+
630
781
  & + .button {
631
782
  margin-top: 10px !important;
632
783
  }
784
+ }
785
+
786
+ .el-button-secondary {
787
+ border-color: transparent !important;
788
+ background-color: transparent !important;
789
+ color: inherit !important;
790
+
633
791
  &:hover {
634
- color: #fff !important;
635
- background: #ac76c5 !important;
636
- border: 1px solid #ac76c5 !important;
792
+ color: $app-primary-color !important;
793
+ border-color: $app-primary-color !important;
794
+ background-color: #f9f2fc !important;
637
795
  }
638
796
  }
639
797
 
798
+ .buttons-row {
799
+ text-align: right;
800
+
801
+ .button {
802
+ cursor: default;
803
+ border-color: transparent;
804
+
805
+ &:hover {
806
+ background-color: $app-primary-color !important;
807
+ border-color: transparent !important;
808
+ }
809
+ }
810
+
811
+ .el-button + .el-button {
812
+ margin-top: 0 !important;
813
+ margin-left: 10px !important;
814
+ }
815
+ }
816
+
817
+ .population-display {
818
+ display: flex;
819
+ flex: 1 1 auto !important;
820
+ flex-direction: row !important;
821
+ align-items: center;
822
+ justify-content: space-between;
823
+ border-bottom: 1px solid $app-primary-color;
824
+ padding-bottom: 0.5rem !important;
825
+ }
826
+
640
827
  .tooltip-container {
641
828
  &::after,
642
829
  &::before {
@@ -696,39 +883,18 @@ export default {
696
883
 
697
884
  .content-container {
698
885
  flex: 1 1 100%;
699
- padding: 1rem;
886
+ padding: 0;
700
887
  box-sizing: border-box;
888
+ display: flex;
889
+ flex-direction: column;
890
+ gap: 1rem;
701
891
 
702
- .block {
703
- padding-top: 0.5em;
704
-
705
- + .block {
706
- margin-top: 1rem;
707
- }
708
- }
709
-
710
- .connectivity-info-title ~ & {
711
- padding-top: 0;
892
+ > div,
893
+ > .block + .block {
894
+ margin: 0;
712
895
  }
713
896
  }
714
897
 
715
- .scrollbar::-webkit-scrollbar-track {
716
- border-radius: 10px;
717
- background-color: #f5f5f5;
718
- }
719
-
720
- .scrollbar::-webkit-scrollbar {
721
- width: 12px;
722
- right: -12px;
723
- background-color: #f5f5f5;
724
- }
725
-
726
- .scrollbar::-webkit-scrollbar-thumb {
727
- border-radius: 4px;
728
- box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.06);
729
- background-color: #979797;
730
- }
731
-
732
898
  /* Fix for chrome bug where under triangle pops up above one on top of it */
733
899
  .selector:not(*:root),
734
900
  .tooltip-container::after {
@@ -30,13 +30,15 @@
30
30
  />
31
31
  <template v-for="tab in tabs" key="tab.id">
32
32
  <!-- Connectivity Info -->
33
- <template v-if="tab.type === 'connectivity'">
33
+ <template v-if="tab.type === 'connectivity' && connectivityInfo">
34
34
  <connectivity-info
35
35
  :entry="connectivityInfo"
36
36
  :availableAnatomyFacets="availableAnatomyFacets"
37
- v-show="tab.id === activeTabId"
37
+ v-if="tab.id === activeTabId"
38
+ :envVars="envVars"
38
39
  :ref="'connectivityTab_' + tab.id"
39
40
  @show-connectivity="showConnectivity"
41
+ @connectivity-component-click="onConnectivityComponentClick"
40
42
  />
41
43
  </template>
42
44
  <template v-else-if="tab.type === 'annotation'">
@@ -180,6 +182,13 @@ export default {
180
182
  showConnectivity: function (featureIds) {
181
183
  this.$emit('show-connectivity', featureIds);
182
184
  },
185
+ /**
186
+ * This function is triggered after a connectivity component is clicked.
187
+ * @arg data
188
+ */
189
+ onConnectivityComponentClick: function (data) {
190
+ this.$emit('connectivity-component-click', data);
191
+ },
183
192
  /**
184
193
  * This event is emitted when the search filters are changed.
185
194
  * @arg `obj` {data, id}
@@ -291,6 +300,13 @@ export default {
291
300
  tabClose: function (id) {
292
301
  this.$emit('tab-close', id);
293
302
  },
303
+ /**
304
+ * To receive error message for connectivity graph
305
+ * @param {String} errorMessage
306
+ */
307
+ updateConnectivityGraphError: function (errorInfo) {
308
+ EventBus.emit('connectivity-graph-error', errorInfo);
309
+ },
294
310
  },
295
311
  computed: {
296
312
  activeTabs: function() {
@@ -16,7 +16,7 @@
16
16
  </div>
17
17
  </div>
18
18
  <el-button
19
- v-if="title.id !== 1"
19
+ v-if="title.id > 1"
20
20
  @click="tabClose(title.id)"
21
21
  class="button-tab-close"
22
22
  aria-label="Close"