@abi-software/map-side-bar 2.7.2-beta.0 → 2.7.2-beta.2

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.
@@ -5,7 +5,9 @@
5
5
  <div class="title-content">
6
6
  <div class="block" v-if="entry.title">
7
7
  <div class="title">
8
- {{ capitalise(entry.title) }}
8
+ <span @click="connectivityClicked(entry.featureId[0])">
9
+ {{ capitalise(entry.title) }}
10
+ </span>
9
11
  <template v-if="entry.featuresAlert">
10
12
  <el-popover
11
13
  width="250"
@@ -22,13 +24,7 @@
22
24
  </el-popover>
23
25
  </template>
24
26
  </div>
25
- <div
26
- v-if="
27
- entry.provenanceTaxonomyLabel &&
28
- entry.provenanceTaxonomyLabel.length > 0
29
- "
30
- class="subtitle"
31
- >
27
+ <div v-if="hasProvenanceTaxonomyLabel" class="subtitle">
32
28
  {{ provSpeciesDescription }}
33
29
  </div>
34
30
  </div>
@@ -80,7 +76,7 @@
80
76
 
81
77
  <div class="content-container content-container-connectivity" v-show="activeView === 'listView'">
82
78
  {{ entry.paths }}
83
- <div v-if="entry.origins && entry.origins.length > 0" class="block">
79
+ <div v-if="hasOrigins" class="block">
84
80
  <div class="attribute-title-container">
85
81
  <span class="attribute-title">Origin</span>
86
82
  <el-popover
@@ -95,7 +91,6 @@
95
91
  <span style="word-break: keep-all">
96
92
  <i>Origin</i> {{ originDescription }}
97
93
  </span>
98
-
99
94
  </el-popover>
100
95
  </div>
101
96
  <div
@@ -103,16 +98,22 @@
103
98
  class="attribute-content"
104
99
  :origin-item-label="origin"
105
100
  :key="origin"
106
- @mouseenter="toggleConnectivityTooltip(origin, {show: true})"
107
- @mouseleave="toggleConnectivityTooltip(origin, {show: false})"
108
101
  >
109
- {{ capitalise(origin) }}
102
+ <span
103
+ @mouseenter="connectivityHovered(origin)"
104
+ @mouseleave="connectivityHovered()"
105
+ >
106
+ {{ capitalise(origin) }}
107
+ </span>
108
+ <el-icon
109
+ class="connectivity-search-icon"
110
+ @click="connectivityClicked(entry.featureId[0], 'Origins', origin)"
111
+ >
112
+ <el-icon-search />
113
+ </el-icon>
110
114
  </div>
111
115
  <el-button
112
- v-show="
113
- entry.originsWithDatasets && entry.originsWithDatasets.length > 0 &&
114
- shouldShowExploreButton(entry.originsWithDatasets)
115
- "
116
+ v-show="hasOriginsWithDatasets"
116
117
  class="button"
117
118
  id="open-dendrites-button"
118
119
  @click="openDendrites"
@@ -120,10 +121,7 @@
120
121
  Explore origin data
121
122
  </el-button>
122
123
  </div>
123
- <div
124
- v-if="entry.components && entry.components.length > 0"
125
- class="block"
126
- >
124
+ <div v-if="hasComponents" class="block">
127
125
  <div class="attribute-title-container">
128
126
  <div class="attribute-title">Components</div>
129
127
  </div>
@@ -132,16 +130,22 @@
132
130
  class="attribute-content"
133
131
  :component-item-label="component"
134
132
  :key="component"
135
- @mouseenter="toggleConnectivityTooltip(component, {show: true})"
136
- @mouseleave="toggleConnectivityTooltip(component, {show: false})"
137
133
  >
138
- {{ capitalise(component) }}
134
+ <span
135
+ @mouseenter="connectivityHovered(component)"
136
+ @mouseleave="connectivityHovered()"
137
+ >
138
+ {{ capitalise(component) }}
139
+ </span>
140
+ <el-icon
141
+ class="connectivity-search-icon"
142
+ @click="connectivityClicked(entry.featureId[0], 'Components', component)"
143
+ >
144
+ <el-icon-search />
145
+ </el-icon>
139
146
  </div>
140
147
  </div>
141
- <div
142
- v-if="entry.destinations && entry.destinations.length > 0"
143
- class="block"
144
- >
148
+ <div v-if="hasDestinations" class="block">
145
149
  <div class="attribute-title-container">
146
150
  <span class="attribute-title">Destination</span>
147
151
  <el-popover
@@ -163,35 +167,27 @@
163
167
  class="attribute-content"
164
168
  :destination-item-label="destination"
165
169
  :key="destination"
166
- @mouseenter="toggleConnectivityTooltip(destination, {show: true})"
167
- @mouseleave="toggleConnectivityTooltip(destination, {show: false})"
168
170
  >
169
- {{ capitalise(destination) }}
171
+ <span
172
+ @mouseenter="connectivityHovered(destination)"
173
+ @mouseleave="connectivityHovered()"
174
+ >
175
+ {{ capitalise(destination) }}
176
+ </span>
177
+ <el-icon
178
+ class="connectivity-search-icon"
179
+ @click="connectivityClicked(entry.featureId[0], 'Destinations', destination)"
180
+ >
181
+ <el-icon-search />
182
+ </el-icon>
170
183
  </div>
171
- <el-button
172
- v-show="
173
- entry.destinationsWithDatasets &&
174
- entry.destinationsWithDatasets.length > 0 &&
175
- shouldShowExploreButton(entry.destinationsWithDatasets)
176
- "
177
- class="button"
178
- @click="openAxons"
184
+ <el-button v-show="hasDestinationsWithDatasets" class="button" @click="openAxons"
179
185
  >
180
186
  Explore destination data
181
187
  </el-button>
182
188
  </div>
183
- <div
184
- v-show="
185
- entry.componentsWithDatasets &&
186
- entry.componentsWithDatasets.length > 0 &&
187
- shouldShowExploreButton(entry.componentsWithDatasets)
188
- "
189
- class="block"
190
- >
191
- <el-button
192
- class="button"
193
- @click="openAll"
194
- >
189
+ <div v-show="hasComponentsWithDatasets" class="block">
190
+ <el-button class="button" @click="openAll">
195
191
  Search for data on components
196
192
  </el-button>
197
193
  </div>
@@ -220,22 +216,22 @@
220
216
  </div>
221
217
 
222
218
  <div class="content-container content-container-references" v-if="resources.length">
223
- <external-resource-card
219
+ <ExternalResourceCard
224
220
  :resources="resources"
225
221
  @references-loaded="onReferencesLoaded"
226
222
  @show-reference-connectivities="onShowReferenceConnectivities"
227
- ></external-resource-card>
223
+ />
228
224
  </div>
229
225
  </div>
230
226
  </template>
231
227
 
232
228
  <script>
229
+ /* eslint-disable no-alert, no-console */
233
230
  import {
234
- ArrowUp as ElIconArrowUp,
235
- ArrowDown as ElIconArrowDown,
236
231
  Warning as ElIconWarning,
232
+ Location as ElIconLocation,
233
+ Search as ElIconSearch,
237
234
  } from '@element-plus/icons-vue'
238
- /* eslint-disable no-alert, no-console */
239
235
  import {
240
236
  ElButton as Button,
241
237
  ElContainer as Container,
@@ -246,7 +242,7 @@ import EventBus from './EventBus.js'
246
242
  import {
247
243
  CopyToClipboard,
248
244
  ConnectivityGraph,
249
- ExternalResourceCard,
245
+ ExternalResourceCard
250
246
  } from '@abi-software/map-utilities';
251
247
  import '@abi-software/map-utilities/dist/style.css';
252
248
 
@@ -269,12 +265,12 @@ export default {
269
265
  Button,
270
266
  Container,
271
267
  Icon,
272
- ElIconArrowUp,
273
- ElIconArrowDown,
274
268
  ElIconWarning,
275
- ExternalResourceCard,
269
+ ElIconLocation,
270
+ ElIconSearch,
276
271
  CopyToClipboard,
277
272
  ConnectivityGraph,
273
+ ExternalResourceCard
278
274
  },
279
275
  props: {
280
276
  entry: {
@@ -313,7 +309,6 @@ export default {
313
309
  motor: 'is the location of the initial cell body of the circuit',
314
310
  sensory: 'is the location of the initial cell body in the PNS circuit',
315
311
  },
316
- componentsWithDatasets: [],
317
312
  uberons: [{ id: undefined, name: undefined }],
318
313
  connectivityError: null,
319
314
  timeoutID: undefined,
@@ -332,6 +327,42 @@ export default {
332
327
  },
333
328
  },
334
329
  computed: {
330
+ hasProvenanceTaxonomyLabel: function () {
331
+ return (
332
+ this.entry.provenanceTaxonomyLabel &&
333
+ this.entry.provenanceTaxonomyLabel.length > 0
334
+ );
335
+ },
336
+ hasOrigins: function () {
337
+ return this.entry.origins && this.entry.origins.length > 0;
338
+ },
339
+ hasOriginsWithDatasets: function () {
340
+ return (
341
+ this.entry.originsWithDatasets &&
342
+ this.entry.originsWithDatasets.length > 0 &&
343
+ this.shouldShowExploreButton(this.entry.originsWithDatasets)
344
+ );
345
+ },
346
+ hasComponents: function () {
347
+ return this.entry.components && this.entry.components.length > 0;
348
+ },
349
+ hasComponentsWithDatasets: function () {
350
+ return (
351
+ this.entry.componentsWithDatasets &&
352
+ this.entry.componentsWithDatasets.length > 0 &&
353
+ this.shouldShowExploreButton(this.entry.componentsWithDatasets)
354
+ );
355
+ },
356
+ hasDestinations: function () {
357
+ return this.entry.destinations && this.entry.destinations.length > 0;
358
+ },
359
+ hasDestinationsWithDatasets: function () {
360
+ return (
361
+ this.entry.destinationsWithDatasets &&
362
+ this.entry.destinationsWithDatasets.length > 0 &&
363
+ this.shouldShowExploreButton(this.entry.destinationsWithDatasets)
364
+ );
365
+ },
335
366
  resources: function () {
336
367
  let resources = [];
337
368
  if (this.entry && this.entry.hyperlinks) {
@@ -418,7 +449,6 @@ export default {
418
449
  },
419
450
  switchConnectivityView: function (val) {
420
451
  this.activeView = val;
421
-
422
452
  if (val === 'graphView' && !this.graphViewLoaded) {
423
453
  // to load the connectivity graph only after the container is in view
424
454
  this.$nextTick(() => {
@@ -429,7 +459,7 @@ export default {
429
459
  onTapNode: function (data) {
430
460
  // save selected state for list view
431
461
  const name = data.map(t => t.label).join(', ');
432
- this.toggleConnectivityTooltip(name, {show: true});
462
+ this.connectivityHovered(name);
433
463
  },
434
464
  onShowReferenceConnectivities: function (refSource) {
435
465
  this.$emit('show-reference-connectivities', refSource);
@@ -539,31 +569,48 @@ export default {
539
569
 
540
570
  return contentArray.join('\n\n<br>');
541
571
  },
542
- toggleConnectivityTooltip: function (name, option) {
572
+ getConnectivityDatasets: function (label) {
543
573
  const allWithDatasets = [
544
574
  ...this.entry.componentsWithDatasets,
545
575
  ...this.entry.destinationsWithDatasets,
546
576
  ...this.entry.originsWithDatasets,
547
577
  ];
548
- const names = name.split(','); // some features have more than one value
549
- const data = [];
550
- if (option.show) {
551
- names.forEach((n) => {
552
- const foundData = allWithDatasets.find((a) =>
553
- a.name.toLowerCase().trim() === n.toLowerCase().trim()
554
- );
555
-
556
- if (foundData) {
557
- data.push({
558
- id: foundData.id,
559
- label: foundData.name
560
- });
561
- }
562
- });
563
- }
564
-
578
+ const names = label.split(','); // some features have more than one value
579
+ let data = [];
580
+ names.forEach((n) => {
581
+ const foundData = allWithDatasets.find((a) =>
582
+ a.name.toLowerCase().trim() === n.toLowerCase().trim()
583
+ );
584
+ if (foundData) {
585
+ data.push({
586
+ id: foundData.id,
587
+ label: foundData.name
588
+ });
589
+ }
590
+ });
591
+ return data
592
+ },
593
+ connectivityHovered: function (label) {
594
+ const data = label ? this.getConnectivityDatasets(label) : [];
565
595
  // type: to show error only for click event
566
- this.$emit('connectivity-component-click', data);
596
+ this.$emit('connectivity-hovered', data);
597
+ },
598
+ connectivityClicked: function (id, type, label) {
599
+ let payload = {
600
+ query: id,
601
+ filter: [],
602
+ data: label ? this.getConnectivityDatasets(label) : [],
603
+ };
604
+ if (type && label) {
605
+ payload.filter.push({
606
+ AND: undefined,
607
+ facet: type,
608
+ facetPropPath: 'flatmap.connectivity.source',
609
+ facetSubPropPath: undefined,
610
+ term: 'Connectivity',
611
+ });
612
+ };
613
+ this.$emit('connectivity-clicked', payload);
567
614
  },
568
615
  getErrorConnectivities: function (errorData) {
569
616
  const errorDataToEmit = [...new Set(errorData)];
@@ -659,6 +706,10 @@ export default {
659
706
  font-weight: bold;
660
707
  padding-bottom: 8px;
661
708
  color: $app-primary-color;
709
+
710
+ span:hover {
711
+ cursor: pointer;
712
+ }
662
713
  }
663
714
 
664
715
  .block + .block {
@@ -774,17 +825,29 @@ export default {
774
825
  }
775
826
 
776
827
  .attribute-content {
828
+ display: flex;
829
+ justify-content: space-between;
777
830
  font-size: 14px;
778
831
  font-weight: 500;
779
832
  transition: color 0.25s ease;
780
833
  position: relative;
781
834
  cursor: default;
782
835
 
836
+ .connectivity-search-icon {
837
+ display: none;
838
+ }
839
+
783
840
  &:hover {
784
841
  color: $app-primary-color;
842
+
843
+ .connectivity-search-icon {
844
+ padding-top: 4px;
845
+ cursor: pointer;
846
+ display: block;
847
+ }
785
848
  }
786
849
 
787
- + .attribute-content {
850
+ +.attribute-content {
788
851
  &::before {
789
852
  content: "";
790
853
  width: 90%;
@@ -864,6 +927,19 @@ export default {
864
927
  }
865
928
  }
866
929
 
930
+ .neuron-connection-button {
931
+ display: flex;
932
+ flex: 1 1 auto !important;
933
+ flex-direction: row !important;
934
+ align-items: center;
935
+ justify-content: space-between;
936
+
937
+ .el-button + .el-button {
938
+ margin-top: 0 !important;
939
+ margin-left: 10px !important;
940
+ }
941
+ }
942
+
867
943
  .population-display {
868
944
  display: flex;
869
945
  flex: 1 1 auto !important;
@@ -213,7 +213,60 @@ export default {
213
213
  )
214
214
  return value
215
215
  },
216
+ processOptions: function () {
217
+ // create top level of options in cascader
218
+ this.options.forEach((facet, i) => {
219
+ this.options[i].total = this.countTotalFacet(facet)
220
+
221
+ this.options[i].label = convertReadableLabel(facet.label)
222
+ this.options[i].value = this.createCascaderItemValue(
223
+ facet.key,
224
+ undefined
225
+ )
226
+
227
+ // put "Show all" as first option
228
+ this.options[i].children.unshift({
229
+ value: this.createCascaderItemValue('Show all'),
230
+ label: 'Show all',
231
+ })
232
+
233
+ // populate second level of options
234
+ this.options[i].children.forEach((facetItem, j) => {
235
+ // Format labels except funding program
236
+ if (this.options[i].children[j].facetPropPath !== 'pennsieve.organization.name') {
237
+ this.options[i].children[j].label = convertReadableLabel(
238
+ facetItem.label
239
+ )
240
+ }
241
+ this.options[i].children[j].value =
242
+ this.createCascaderItemValue(facet.label, facetItem.label)
243
+ if (
244
+ this.options[i].children[j].children &&
245
+ this.options[i].children[j].children.length > 0
246
+ ) {
247
+ this.options[i].children[j].children.forEach((term, k) => {
248
+ this.options[i].children[j].children[k].label =
249
+ convertReadableLabel(term.label)
250
+ this.options[i].children[j].children[k].value =
251
+ this.createCascaderItemValue(
252
+ facet.label,
253
+ facetItem.label,
254
+ term.label
255
+ )
256
+ })
257
+ }
258
+ })
259
+ })
260
+ },
216
261
  populateCascader: function () {
262
+ if (this.entry.options) {
263
+ return new Promise((resolve) => {
264
+ this.facets = this.entry.options
265
+ this.options = this.entry.options
266
+ this.processOptions()
267
+ resolve();
268
+ });
269
+ }
217
270
  return new Promise((resolve) => {
218
271
  // Algolia facet serach
219
272
  this.algoliaClient
@@ -222,50 +275,7 @@ export default {
222
275
  this.facets = data
223
276
  EventBus.emit('available-facets', data)
224
277
  this.options = data
225
-
226
- // create top level of options in cascader
227
- this.options.forEach((facet, i) => {
228
- this.options[i].total = this.countTotalFacet(facet)
229
-
230
- this.options[i].label = convertReadableLabel(facet.label)
231
- this.options[i].value = this.createCascaderItemValue(
232
- facet.key,
233
- undefined
234
- )
235
-
236
- // put "Show all" as first option
237
- this.options[i].children.unshift({
238
- value: this.createCascaderItemValue('Show all'),
239
- label: 'Show all',
240
- })
241
-
242
- // populate second level of options
243
- this.options[i].children.forEach((facetItem, j) => {
244
- // Format labels except funding program
245
- if (this.options[i].children[j].facetPropPath !== 'pennsieve.organization.name') {
246
- this.options[i].children[j].label = convertReadableLabel(
247
- facetItem.label
248
- )
249
- }
250
- this.options[i].children[j].value =
251
- this.createCascaderItemValue(facet.label, facetItem.label)
252
- if (
253
- this.options[i].children[j].children &&
254
- this.options[i].children[j].children.length > 0
255
- ) {
256
- this.options[i].children[j].children.forEach((term, k) => {
257
- this.options[i].children[j].children[k].label =
258
- convertReadableLabel(term.label)
259
- this.options[i].children[j].children[k].value =
260
- this.createCascaderItemValue(
261
- facet.label,
262
- facetItem.label,
263
- term.label
264
- )
265
- })
266
- }
267
- })
268
- })
278
+ this.processOptions()
269
279
  })
270
280
  .finally(() => {
271
281
  resolve()
@@ -735,13 +745,18 @@ export default {
735
745
  removeTopLevelCascaderCheckboxes: function () {
736
746
  // Next tick allows the cascader menu to change
737
747
  this.$nextTick(() => {
738
- let cascadePanels = document.querySelectorAll(
739
- '.sidebar-cascader-popper .el-cascader-menu__list'
740
- )
741
- // Hide the checkboxes on the first level of the cascader
742
- cascadePanels[0]
743
- .querySelectorAll('.el-checkbox__input')
744
- .forEach((el) => (el.style.display = 'none'))
748
+ const cascadePanels = document.querySelectorAll('.sidebar-cascader-popper .el-cascader-menu__list');
749
+
750
+ cascadePanels.forEach(panel => {
751
+ const panelText = panel.textContent;
752
+ const expandArrow = panel.querySelector('.el-icon.arrow-right');
753
+
754
+ if (!panelText.includes('Show all') && expandArrow) {
755
+ panel.querySelectorAll('.el-checkbox__input').forEach(checkbox => {
756
+ checkbox.style.display = 'none';
757
+ });
758
+ }
759
+ });
745
760
  })
746
761
  },
747
762
  /*