@abi-software/map-side-bar 2.3.0 → 2.4.0-alpha-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.
Files changed (43) hide show
  1. package/.eslintrc.js +12 -12
  2. package/.postcssrc.json +5 -5
  3. package/LICENSE +201 -201
  4. package/README.md +168 -168
  5. package/cypress.config.js +23 -23
  6. package/dist/data/pmr-sample.json +3181 -0
  7. package/dist/map-side-bar.js +15142 -9024
  8. package/dist/map-side-bar.umd.cjs +50 -103
  9. package/dist/style.css +1 -1
  10. package/package.json +77 -77
  11. package/public/data/pmr-sample.json +3181 -0
  12. package/reporter-config.json +9 -9
  13. package/src/App.vue +266 -265
  14. package/src/algolia/algolia.js +255 -242
  15. package/src/algolia/utils.js +100 -100
  16. package/src/assets/_variables.scss +43 -43
  17. package/src/assets/styles.scss +6 -6
  18. package/src/components/BadgesGroup.vue +124 -124
  19. package/src/components/ConnectivityInfo.vue +619 -619
  20. package/src/components/DatasetCard.vue +367 -357
  21. package/src/components/EventBus.js +3 -3
  22. package/src/components/ExternalResourceCard.vue +113 -113
  23. package/src/components/FlatmapDatasetCard.vue +171 -0
  24. package/src/components/ImageGallery.vue +542 -542
  25. package/src/components/PMRDatasetCard.vue +237 -0
  26. package/src/components/SearchFilters.vue +1023 -1006
  27. package/src/components/SearchHistory.vue +175 -175
  28. package/src/components/SideBar.vue +436 -436
  29. package/src/components/SidebarContent.vue +730 -603
  30. package/src/components/Tabs.vue +145 -145
  31. package/src/components/allPaths.js +5928 -0
  32. package/src/components/index.js +8 -8
  33. package/src/components/pmrTest.js +4 -0
  34. package/src/components/species-map.js +8 -8
  35. package/src/components.d.ts +2 -0
  36. package/src/exampleConnectivityInput.js +291 -291
  37. package/src/flatmapQueries/flatmapQueries.js +169 -0
  38. package/src/main.js +9 -9
  39. package/src/mixins/S3Bucket.vue +37 -37
  40. package/src/mixins/mixedPageCalculation.vue +78 -0
  41. package/static.json +6 -6
  42. package/vite.config.js +55 -55
  43. package/vuese-generator.js +65 -65
@@ -1,619 +1,619 @@
1
- <template>
2
- <div v-if="entry" class="main" v-loading="loading">
3
- <!-- Connectivity Info Title -->
4
- <div class="connectivity-info-title">
5
- <div>
6
- <div class="block" v-if="entry.title">
7
- <div class="title">{{ capitalise(entry.title) }}</div>
8
- <div
9
- v-if="
10
- entry.provenanceTaxonomyLabel &&
11
- entry.provenanceTaxonomyLabel.length > 0
12
- "
13
- class="subtitle"
14
- >
15
- {{ provSpeciesDescription }}
16
- </div>
17
- </div>
18
- <div class="block" v-else>
19
- <div class="title">{{ entry.featureId }}</div>
20
- </div>
21
- <external-resource-card :resources="resources"></external-resource-card>
22
- </div>
23
- <div>
24
- <el-popover
25
- width="200"
26
- trigger="hover"
27
- :teleported="false"
28
- popper-class="popover-origin-help"
29
- >
30
- <template #reference>
31
- <el-button class="button-circle" circle @click="showConnectivity(entry)">
32
- <el-icon color="white">
33
- <el-icon-location />
34
- </el-icon>
35
- </el-button>
36
- </template>
37
- <span>
38
- Show connectivity on map
39
- </span>
40
- </el-popover>
41
- </div>
42
- </div>
43
- <div v-if="featuresAlert" class="attribute-title-container">
44
- <span class="attribute-title">Alert</span>
45
- <el-popover
46
- width="250"
47
- trigger="hover"
48
- :teleported="false"
49
- popper-class="popover-origin-help"
50
- >
51
- <template #reference>
52
- <el-icon class="info"><el-icon-warning /></el-icon>
53
- </template>
54
- <span style="word-break: keep-all">
55
- {{ featuresAlert }}
56
- </span>
57
- </el-popover>
58
- </div>
59
- <div class="content-container scrollbar">
60
- {{ entry.paths }}
61
- <div v-if="entry.origins && entry.origins.length > 0" class="block">
62
- <div class="attribute-title-container">
63
- <span class="attribute-title">Origin</span>
64
- <el-popover
65
- width="250"
66
- trigger="hover"
67
- :teleported="false"
68
- popper-class="popover-origin-help"
69
- >
70
- <template #reference>
71
- <el-icon class="info"><el-icon-warning /></el-icon>
72
- </template>
73
- <span style="word-break: keep-all">
74
- <i>Origin</i> {{ originDescription }}
75
- </span>
76
-
77
- </el-popover>
78
- </div>
79
- <div
80
- v-for="(origin, i) in entry.origins"
81
- class="attribute-content"
82
- :origin-item-label="origin"
83
- :key="origin"
84
- >
85
- {{ capitalise(origin) }}
86
- <div v-if="i != entry.origins.length - 1" class="seperator"></div>
87
- </div>
88
- <el-button
89
- v-show="
90
- entry.originsWithDatasets && entry.originsWithDatasets.length > 0 &&
91
- shouldShowExploreButton(entry.originsWithDatasets)
92
- "
93
- class="button"
94
- id="open-dendrites-button"
95
- @click="openDendrites"
96
- >
97
- Explore origin data
98
- </el-button>
99
- </div>
100
- <div
101
- v-if="entry.components && entry.components.length > 0"
102
- class="block"
103
- >
104
- <div class="attribute-title-container">
105
- <div class="attribute-title">Components</div>
106
- </div>
107
- <div
108
- v-for="(component, i) in entry.components"
109
- class="attribute-content"
110
- :component-item-label="component"
111
- :key="component"
112
- >
113
- {{ capitalise(component) }}
114
- <div
115
- v-if="i != entry.components.length - 1"
116
- class="seperator"
117
- ></div>
118
- </div>
119
- </div>
120
- <div
121
- v-if="entry.destinations && entry.destinations.length > 0"
122
- class="block"
123
- >
124
- <div class="attribute-title-container">
125
- <span class="attribute-title">Destination</span>
126
- <el-popover
127
- width="250"
128
- trigger="hover"
129
- :teleported="false"
130
- popper-class="popover-origin-help"
131
- >
132
- <template #reference>
133
- <el-icon class="info"><el-icon-warning /></el-icon>
134
- </template>
135
- <span style="word-break: keep-all">
136
- <i>Destination</i> is where the axons terminate
137
- </span>
138
- </el-popover>
139
- </div>
140
- <div
141
- v-for="(destination, i) in entry.destinations"
142
- class="attribute-content"
143
- :destination-item-label="destination"
144
- :key="destination"
145
- >
146
- {{ capitalise(destination) }}
147
- <div
148
- v-if="i != entry.destinations.length - 1"
149
- class="seperator"
150
- ></div>
151
- </div>
152
- <el-button
153
- v-show="
154
- entry.destinationsWithDatasets &&
155
- entry.destinationsWithDatasets.length > 0 &&
156
- shouldShowExploreButton(entry.destinationsWithDatasets)
157
- "
158
- class="button"
159
- @click="openAxons"
160
- >
161
- Explore destination data
162
- </el-button>
163
- </div>
164
-
165
- <el-button
166
- v-show="
167
- entry.componentsWithDatasets &&
168
- entry.componentsWithDatasets.length > 0 &&
169
- shouldShowExploreButton(entry.componentsWithDatasets)
170
- "
171
- class="button"
172
- @click="openAll"
173
- >
174
- Search for data on components
175
- </el-button>
176
- </div>
177
- </div>
178
- </template>
179
-
180
- <script>
181
- import {
182
- ArrowUp as ElIconArrowUp,
183
- ArrowDown as ElIconArrowDown,
184
- Warning as ElIconWarning,
185
- } from '@element-plus/icons-vue'
186
- /* eslint-disable no-alert, no-console */
187
- import {
188
- ElButton as Button,
189
- ElContainer as Container,
190
- ElIcon as Icon,
191
- } from 'element-plus'
192
- import ExternalResourceCard from './ExternalResourceCard.vue'
193
- import EventBus from './EventBus.js'
194
-
195
- const titleCase = (str) => {
196
- return str.replace(/\w\S*/g, (t) => {
197
- return t.charAt(0).toUpperCase() + t.substr(1).toLowerCase()
198
- })
199
- }
200
-
201
- const capitalise = function (str) {
202
- if (str) return str.charAt(0).toUpperCase() + str.slice(1)
203
- return ''
204
- }
205
-
206
- export default {
207
- name: 'ConnectivityInfo',
208
- components: {
209
- Button,
210
- Container,
211
- Icon,
212
- ElIconArrowUp,
213
- ElIconArrowDown,
214
- ElIconWarning,
215
- ExternalResourceCard,
216
- },
217
- props: {
218
- entry: {
219
- type: Object,
220
- default: () => ({
221
- destinations: [],
222
- origins: [],
223
- components: [],
224
- destinationsWithDatasets: [],
225
- originsWithDatasets: [],
226
- componentsWithDatasets: [],
227
- resource: undefined,
228
- }),
229
- },
230
- availableAnatomyFacets: {
231
- type: Array,
232
- default: () => [],
233
- },
234
- },
235
- // inject: ['getFeaturesAlert'],
236
- data: function () {
237
- return {
238
- controller: undefined,
239
- activeSpecies: undefined,
240
- pubmedSearchUrl: '',
241
- loading: false,
242
- facetList: [],
243
- showToolip: false,
244
- showDetails: false,
245
- originDescriptions: {
246
- motor: 'is the location of the initial cell body of the circuit',
247
- sensory: 'is the location of the initial cell body in the PNS circuit',
248
- },
249
- componentsWithDatasets: [],
250
- uberons: [{ id: undefined, name: undefined }],
251
- }
252
- },
253
- watch: {
254
- availableAnatomyFacets: {
255
- handler: function (val) {
256
- this.convertFacetsToList(val)
257
- },
258
- immediate: true,
259
- deep: true,
260
- },
261
- },
262
- computed: {
263
- resources: function () {
264
- let resources = [];
265
- if (this.entry && this.entry.hyperlinks) {
266
- resources = this.entry.hyperlinks;
267
- }
268
- return resources;
269
- },
270
- featuresAlert() {
271
- // return this.getFeaturesAlert()
272
- },
273
- originDescription: function () {
274
- if (
275
- this.entry &&
276
- this.entry.title &&
277
- this.entry.title.toLowerCase().includes('motor')
278
- ) {
279
- return this.originDescriptions.motor
280
- } else {
281
- return this.originDescriptions.sensory
282
- }
283
- },
284
- provSpeciesDescription: function () {
285
- let text = 'Studied in'
286
- this.entry.provenanceTaxonomyLabel.forEach((label) => {
287
- text += ` ${label},`
288
- })
289
- text = text.slice(0, -1) // remove last comma
290
- text += ' species'
291
- return text
292
- },
293
- },
294
- methods: {
295
- titleCase: function (title) {
296
- return titleCase(title)
297
- },
298
- capitalise: function (text) {
299
- return capitalise(text)
300
- },
301
- openUrl: function (url) {
302
- window.open(url, '_blank')
303
- },
304
- openAll: function () {
305
- EventBus.emit('onConnectivityActionClick', {
306
- type: 'Facets',
307
- labels: this.entry.componentsWithDatasets.map((a) => a.name.toLowerCase()),
308
- })
309
- },
310
- openAxons: function () {
311
- EventBus.emit('onConnectivityActionClick', {
312
- type: 'Facets',
313
- labels: this.entry.destinationsWithDatasets.map((a) => a.name.toLowerCase()),
314
- })
315
- },
316
- // shouldShowExploreButton: Checks if the feature is in the list of available anatomy facets
317
- shouldShowExploreButton: function (features) {
318
- for (let i = 0; i < features.length; i++) {
319
- if (this.facetList.includes(features[i].name.toLowerCase())) {
320
- return true
321
- }
322
- }
323
- return false
324
- },
325
- // convertFacetsToList: Converts the available anatomy facets to a list for easy searching
326
- convertFacetsToList: function (facets) {
327
- facets.forEach((facet) => {
328
- if(facet.children) {
329
- this.convertFacetsToList(facet.children)
330
- } else {
331
- this.facetList.push(facet.label.toLowerCase())
332
- }
333
- })
334
- },
335
- openDendrites: function () {
336
- EventBus.emit('onConnectivityActionClick', {
337
- type: 'Facets',
338
- labels: this.entry.originsWithDatasets.map((a) => a.name.toLowerCase()),
339
- })
340
- },
341
- pubmedSearchUrlUpdate: function (val) {
342
- this.pubmedSearchUrl = val
343
- },
344
- showConnectivity: function (entry) {
345
- // move the map center to highlighted area
346
- const featureIds = entry.featureId || [];
347
- // connected to flatmapvuer > moveMap(featureIds) function
348
- this.$emit('show-connectivity', featureIds);
349
- },
350
- },
351
- }
352
- </script>
353
-
354
- <style lang="scss" scoped>
355
-
356
- .display {
357
- width: 44px;
358
- word-break: normal;
359
- }
360
-
361
- .connectivity-info-title {
362
- padding: 1rem;
363
- display: flex;
364
- flex-direction: row;
365
- justify-content: space-between;
366
- gap: 1rem;
367
- }
368
-
369
- .title {
370
- text-align: left;
371
- // width: 16em;
372
- line-height: 1.3em !important;
373
- font-size: 18px;
374
- font-family: Helvetica;
375
- font-weight: bold;
376
- padding-bottom: 8px;
377
- color: $app-primary-color;
378
- }
379
-
380
- .block {
381
- margin-bottom: 0.5em;
382
-
383
- .main > &:first-of-type {
384
- margin-right: 1em;
385
- }
386
- }
387
-
388
- .pub {
389
- width: 16rem;
390
- }
391
-
392
- .button-circle {
393
- width: 24px !important;
394
- height: 24px !important;
395
-
396
- &,
397
- &:hover,
398
- &:focus,
399
- &:active {
400
- background-color: $app-primary-color;
401
- border-color: $app-primary-color;
402
- }
403
- }
404
-
405
- .icon {
406
- right: 0px;
407
- position: absolute;
408
- top: 10px;
409
- }
410
-
411
- .icon:hover {
412
- cursor: pointer;
413
- }
414
-
415
- :deep(.popover-origin-help.el-popover) {
416
- text-transform: none !important; // need to overide the tooltip text transform
417
- border: 1px solid $app-primary-color;
418
- .el-popper__arrow {
419
- &:before {
420
- border-color: $app-primary-color;
421
- background-color: #ffffff;
422
- }
423
- }
424
- }
425
-
426
- .info {
427
- transform: rotate(180deg);
428
- color: #8300bf;
429
- margin-left: 8px;
430
- }
431
-
432
- .seperator {
433
- width: 90%;
434
- height: 1px;
435
- background-color: #bfbec2;
436
- }
437
-
438
- .hide {
439
- color: $app-primary-color;
440
- cursor: pointer;
441
- margin-right: 6px;
442
- margin-top: 3px;
443
- }
444
-
445
- .slide-fade-enter-active {
446
- transition: opacity 0.5s, transform 0.5s;
447
- }
448
- .slide-fade-leave-active {
449
- transition: opacity 0.2s, transform 0.2s;
450
- }
451
- .slide-fade-enter, .slide-fade-leave-to /* .slide-fade-leave-active in <2.1.8 */ {
452
- opacity: 0;
453
- transform: translateY(-8px);
454
- }
455
-
456
- .main {
457
- font-size: 14px;
458
- text-align: left;
459
- line-height: 1.5em;
460
- font-family: Asap, sans-serif, Helvetica;
461
- font-weight: 400;
462
- /* outline: thin red solid; */
463
- overflow-y: auto;
464
- scrollbar-width: thin;
465
- min-width: 16rem;
466
- background-color: #f7faff;
467
- height: 100%;
468
- border-left: 1px solid var(--el-border-color);
469
- border-top: 1px solid var(--el-border-color);
470
- }
471
-
472
- .attribute-title-container {
473
- margin-bottom: 0.5em;
474
- }
475
-
476
- .attribute-title {
477
- font-size: 16px;
478
- font-weight: 600;
479
- /* font-weight: bold; */
480
- text-transform: uppercase;
481
- }
482
-
483
- .attribute-content {
484
- font-size: 14px;
485
- font-weight: 500;
486
-
487
- &:last-of-type {
488
- margin-bottom: 0.5em;
489
- }
490
- }
491
-
492
- .popover-container {
493
- height: 100%;
494
- width: 100%;
495
- }
496
-
497
- .main {
498
- .el-button.is-round {
499
- border-radius: 4px;
500
- padding: 9px 20px 10px 20px;
501
- display: flex;
502
- height: 36px;
503
- }
504
- }
505
-
506
- .button {
507
- margin-left: 0px !important;
508
- margin-top: 0px !important;
509
- font-size: 14px !important;
510
- background-color: $app-primary-color;
511
- color: #fff;
512
- & + .button {
513
- margin-top: 10px !important;
514
- }
515
- &:hover {
516
- color: #fff !important;
517
- background: #ac76c5 !important;
518
- border: 1px solid #ac76c5 !important;
519
- }
520
- }
521
-
522
- .tooltip-container {
523
- &::after,
524
- &::before {
525
- content: '';
526
- display: block;
527
- position: absolute;
528
- width: 0;
529
- height: 0;
530
- border-style: solid;
531
- flex-shrink: 0;
532
- }
533
- .tooltip {
534
- &::after {
535
- display: none;
536
- }
537
- &::before {
538
- display: none;
539
- }
540
- }
541
- }
542
-
543
- .maplibregl-popup-anchor-bottom {
544
- .tooltip-container {
545
- &::after,
546
- &::before {
547
- top: 100%;
548
- border-width: 12px;
549
- }
550
- &::after {
551
- margin-top: -1px;
552
- border-color: rgb(255, 255, 255) transparent transparent transparent;
553
- }
554
- &::before {
555
- margin: 0 auto;
556
- border-color: $app-primary-color transparent transparent transparent;
557
- }
558
- }
559
- }
560
-
561
- .maplibregl-popup-anchor-top {
562
- .tooltip-container {
563
- &::after,
564
- &::before {
565
- top: -24px;
566
- border-width: 12px;
567
- }
568
- &::after {
569
- margin-top: 1px;
570
- border-color: transparent transparent rgb(255, 255, 255) transparent;
571
- }
572
- &::before {
573
- margin: 0 auto;
574
- border-color: transparent transparent $app-primary-color transparent;
575
- }
576
- }
577
- }
578
-
579
- .content-container {
580
- flex: 1 1 100%;
581
- padding: 1rem;
582
- box-sizing: border-box;
583
-
584
- .block {
585
- padding-top: 0.5em;
586
-
587
- + .block {
588
- margin-top: 1rem;
589
- }
590
- }
591
-
592
- .connectivity-info-title ~ & {
593
- padding-top: 0;
594
- }
595
- }
596
-
597
- .scrollbar::-webkit-scrollbar-track {
598
- border-radius: 10px;
599
- background-color: #f5f5f5;
600
- }
601
-
602
- .scrollbar::-webkit-scrollbar {
603
- width: 12px;
604
- right: -12px;
605
- background-color: #f5f5f5;
606
- }
607
-
608
- .scrollbar::-webkit-scrollbar-thumb {
609
- border-radius: 4px;
610
- box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.06);
611
- background-color: #979797;
612
- }
613
-
614
- /* Fix for chrome bug where under triangle pops up above one on top of it */
615
- .selector:not(*:root),
616
- .tooltip-container::after {
617
- top: 99.4%;
618
- }
619
- </style>
1
+ <template>
2
+ <div v-if="entry" class="main" v-loading="loading">
3
+ <!-- Connectivity Info Title -->
4
+ <div class="connectivity-info-title">
5
+ <div>
6
+ <div class="block" v-if="entry.title">
7
+ <div class="title">{{ capitalise(entry.title) }}</div>
8
+ <div
9
+ v-if="
10
+ entry.provenanceTaxonomyLabel &&
11
+ entry.provenanceTaxonomyLabel.length > 0
12
+ "
13
+ class="subtitle"
14
+ >
15
+ {{ provSpeciesDescription }}
16
+ </div>
17
+ </div>
18
+ <div class="block" v-else>
19
+ <div class="title">{{ entry.featureId }}</div>
20
+ </div>
21
+ <external-resource-card :resources="resources"></external-resource-card>
22
+ </div>
23
+ <div>
24
+ <el-popover
25
+ width="200"
26
+ trigger="hover"
27
+ :teleported="false"
28
+ popper-class="popover-origin-help"
29
+ >
30
+ <template #reference>
31
+ <el-button class="button-circle" circle @click="showConnectivity(entry)">
32
+ <el-icon color="white">
33
+ <el-icon-location />
34
+ </el-icon>
35
+ </el-button>
36
+ </template>
37
+ <span>
38
+ Show connectivity on map
39
+ </span>
40
+ </el-popover>
41
+ </div>
42
+ </div>
43
+ <div v-if="featuresAlert" class="attribute-title-container">
44
+ <span class="attribute-title">Alert</span>
45
+ <el-popover
46
+ width="250"
47
+ trigger="hover"
48
+ :teleported="false"
49
+ popper-class="popover-origin-help"
50
+ >
51
+ <template #reference>
52
+ <el-icon class="info"><el-icon-warning /></el-icon>
53
+ </template>
54
+ <span style="word-break: keep-all">
55
+ {{ featuresAlert }}
56
+ </span>
57
+ </el-popover>
58
+ </div>
59
+ <div class="content-container scrollbar">
60
+ {{ entry.paths }}
61
+ <div v-if="entry.origins && entry.origins.length > 0" class="block">
62
+ <div class="attribute-title-container">
63
+ <span class="attribute-title">Origin</span>
64
+ <el-popover
65
+ width="250"
66
+ trigger="hover"
67
+ :teleported="false"
68
+ popper-class="popover-origin-help"
69
+ >
70
+ <template #reference>
71
+ <el-icon class="info"><el-icon-warning /></el-icon>
72
+ </template>
73
+ <span style="word-break: keep-all">
74
+ <i>Origin</i> {{ originDescription }}
75
+ </span>
76
+
77
+ </el-popover>
78
+ </div>
79
+ <div
80
+ v-for="(origin, i) in entry.origins"
81
+ class="attribute-content"
82
+ :origin-item-label="origin"
83
+ :key="origin"
84
+ >
85
+ {{ capitalise(origin) }}
86
+ <div v-if="i != entry.origins.length - 1" class="seperator"></div>
87
+ </div>
88
+ <el-button
89
+ v-show="
90
+ entry.originsWithDatasets && entry.originsWithDatasets.length > 0 &&
91
+ shouldShowExploreButton(entry.originsWithDatasets)
92
+ "
93
+ class="button"
94
+ id="open-dendrites-button"
95
+ @click="openDendrites"
96
+ >
97
+ Explore origin data
98
+ </el-button>
99
+ </div>
100
+ <div
101
+ v-if="entry.components && entry.components.length > 0"
102
+ class="block"
103
+ >
104
+ <div class="attribute-title-container">
105
+ <div class="attribute-title">Components</div>
106
+ </div>
107
+ <div
108
+ v-for="(component, i) in entry.components"
109
+ class="attribute-content"
110
+ :component-item-label="component"
111
+ :key="component"
112
+ >
113
+ {{ capitalise(component) }}
114
+ <div
115
+ v-if="i != entry.components.length - 1"
116
+ class="seperator"
117
+ ></div>
118
+ </div>
119
+ </div>
120
+ <div
121
+ v-if="entry.destinations && entry.destinations.length > 0"
122
+ class="block"
123
+ >
124
+ <div class="attribute-title-container">
125
+ <span class="attribute-title">Destination</span>
126
+ <el-popover
127
+ width="250"
128
+ trigger="hover"
129
+ :teleported="false"
130
+ popper-class="popover-origin-help"
131
+ >
132
+ <template #reference>
133
+ <el-icon class="info"><el-icon-warning /></el-icon>
134
+ </template>
135
+ <span style="word-break: keep-all">
136
+ <i>Destination</i> is where the axons terminate
137
+ </span>
138
+ </el-popover>
139
+ </div>
140
+ <div
141
+ v-for="(destination, i) in entry.destinations"
142
+ class="attribute-content"
143
+ :destination-item-label="destination"
144
+ :key="destination"
145
+ >
146
+ {{ capitalise(destination) }}
147
+ <div
148
+ v-if="i != entry.destinations.length - 1"
149
+ class="seperator"
150
+ ></div>
151
+ </div>
152
+ <el-button
153
+ v-show="
154
+ entry.destinationsWithDatasets &&
155
+ entry.destinationsWithDatasets.length > 0 &&
156
+ shouldShowExploreButton(entry.destinationsWithDatasets)
157
+ "
158
+ class="button"
159
+ @click="openAxons"
160
+ >
161
+ Explore destination data
162
+ </el-button>
163
+ </div>
164
+
165
+ <el-button
166
+ v-show="
167
+ entry.componentsWithDatasets &&
168
+ entry.componentsWithDatasets.length > 0 &&
169
+ shouldShowExploreButton(entry.componentsWithDatasets)
170
+ "
171
+ class="button"
172
+ @click="openAll"
173
+ >
174
+ Search for data on components
175
+ </el-button>
176
+ </div>
177
+ </div>
178
+ </template>
179
+
180
+ <script>
181
+ import {
182
+ ArrowUp as ElIconArrowUp,
183
+ ArrowDown as ElIconArrowDown,
184
+ Warning as ElIconWarning,
185
+ } from '@element-plus/icons-vue'
186
+ /* eslint-disable no-alert, no-console */
187
+ import {
188
+ ElButton as Button,
189
+ ElContainer as Container,
190
+ ElIcon as Icon,
191
+ } from 'element-plus'
192
+ import ExternalResourceCard from './ExternalResourceCard.vue'
193
+ import EventBus from './EventBus.js'
194
+
195
+ const titleCase = (str) => {
196
+ return str.replace(/\w\S*/g, (t) => {
197
+ return t.charAt(0).toUpperCase() + t.substr(1).toLowerCase()
198
+ })
199
+ }
200
+
201
+ const capitalise = function (str) {
202
+ if (str) return str.charAt(0).toUpperCase() + str.slice(1)
203
+ return ''
204
+ }
205
+
206
+ export default {
207
+ name: 'ConnectivityInfo',
208
+ components: {
209
+ Button,
210
+ Container,
211
+ Icon,
212
+ ElIconArrowUp,
213
+ ElIconArrowDown,
214
+ ElIconWarning,
215
+ ExternalResourceCard,
216
+ },
217
+ props: {
218
+ entry: {
219
+ type: Object,
220
+ default: () => ({
221
+ destinations: [],
222
+ origins: [],
223
+ components: [],
224
+ destinationsWithDatasets: [],
225
+ originsWithDatasets: [],
226
+ componentsWithDatasets: [],
227
+ resource: undefined,
228
+ }),
229
+ },
230
+ availableAnatomyFacets: {
231
+ type: Array,
232
+ default: () => [],
233
+ },
234
+ },
235
+ // inject: ['getFeaturesAlert'],
236
+ data: function () {
237
+ return {
238
+ controller: undefined,
239
+ activeSpecies: undefined,
240
+ pubmedSearchUrl: '',
241
+ loading: false,
242
+ facetList: [],
243
+ showToolip: false,
244
+ showDetails: false,
245
+ originDescriptions: {
246
+ motor: 'is the location of the initial cell body of the circuit',
247
+ sensory: 'is the location of the initial cell body in the PNS circuit',
248
+ },
249
+ componentsWithDatasets: [],
250
+ uberons: [{ id: undefined, name: undefined }],
251
+ }
252
+ },
253
+ watch: {
254
+ availableAnatomyFacets: {
255
+ handler: function (val) {
256
+ this.convertFacetsToList(val)
257
+ },
258
+ immediate: true,
259
+ deep: true,
260
+ },
261
+ },
262
+ computed: {
263
+ resources: function () {
264
+ let resources = [];
265
+ if (this.entry && this.entry.hyperlinks) {
266
+ resources = this.entry.hyperlinks;
267
+ }
268
+ return resources;
269
+ },
270
+ featuresAlert() {
271
+ // return this.getFeaturesAlert()
272
+ },
273
+ originDescription: function () {
274
+ if (
275
+ this.entry &&
276
+ this.entry.title &&
277
+ this.entry.title.toLowerCase().includes('motor')
278
+ ) {
279
+ return this.originDescriptions.motor
280
+ } else {
281
+ return this.originDescriptions.sensory
282
+ }
283
+ },
284
+ provSpeciesDescription: function () {
285
+ let text = 'Studied in'
286
+ this.entry.provenanceTaxonomyLabel.forEach((label) => {
287
+ text += ` ${label},`
288
+ })
289
+ text = text.slice(0, -1) // remove last comma
290
+ text += ' species'
291
+ return text
292
+ },
293
+ },
294
+ methods: {
295
+ titleCase: function (title) {
296
+ return titleCase(title)
297
+ },
298
+ capitalise: function (text) {
299
+ return capitalise(text)
300
+ },
301
+ openUrl: function (url) {
302
+ window.open(url, '_blank')
303
+ },
304
+ openAll: function () {
305
+ EventBus.emit('onConnectivityActionClick', {
306
+ type: 'Facets',
307
+ labels: this.entry.componentsWithDatasets.map((a) => a.name.toLowerCase()),
308
+ })
309
+ },
310
+ openAxons: function () {
311
+ EventBus.emit('onConnectivityActionClick', {
312
+ type: 'Facets',
313
+ labels: this.entry.destinationsWithDatasets.map((a) => a.name.toLowerCase()),
314
+ })
315
+ },
316
+ // shouldShowExploreButton: Checks if the feature is in the list of available anatomy facets
317
+ shouldShowExploreButton: function (features) {
318
+ for (let i = 0; i < features.length; i++) {
319
+ if (this.facetList.includes(features[i].name.toLowerCase())) {
320
+ return true
321
+ }
322
+ }
323
+ return false
324
+ },
325
+ // convertFacetsToList: Converts the available anatomy facets to a list for easy searching
326
+ convertFacetsToList: function (facets) {
327
+ facets.forEach((facet) => {
328
+ if(facet.children) {
329
+ this.convertFacetsToList(facet.children)
330
+ } else {
331
+ this.facetList.push(facet.label.toLowerCase())
332
+ }
333
+ })
334
+ },
335
+ openDendrites: function () {
336
+ EventBus.emit('onConnectivityActionClick', {
337
+ type: 'Facets',
338
+ labels: this.entry.originsWithDatasets.map((a) => a.name.toLowerCase()),
339
+ })
340
+ },
341
+ pubmedSearchUrlUpdate: function (val) {
342
+ this.pubmedSearchUrl = val
343
+ },
344
+ showConnectivity: function (entry) {
345
+ // move the map center to highlighted area
346
+ const featureIds = entry.featureId || [];
347
+ // connected to flatmapvuer > moveMap(featureIds) function
348
+ this.$emit('show-connectivity', featureIds);
349
+ },
350
+ },
351
+ }
352
+ </script>
353
+
354
+ <style lang="scss" scoped>
355
+
356
+ .display {
357
+ width: 44px;
358
+ word-break: normal;
359
+ }
360
+
361
+ .connectivity-info-title {
362
+ padding: 1rem;
363
+ display: flex;
364
+ flex-direction: row;
365
+ justify-content: space-between;
366
+ gap: 1rem;
367
+ }
368
+
369
+ .title {
370
+ text-align: left;
371
+ // width: 16em;
372
+ line-height: 1.3em !important;
373
+ font-size: 18px;
374
+ font-family: Helvetica;
375
+ font-weight: bold;
376
+ padding-bottom: 8px;
377
+ color: $app-primary-color;
378
+ }
379
+
380
+ .block {
381
+ margin-bottom: 0.5em;
382
+
383
+ .main > &:first-of-type {
384
+ margin-right: 1em;
385
+ }
386
+ }
387
+
388
+ .pub {
389
+ width: 16rem;
390
+ }
391
+
392
+ .button-circle {
393
+ width: 24px !important;
394
+ height: 24px !important;
395
+
396
+ &,
397
+ &:hover,
398
+ &:focus,
399
+ &:active {
400
+ background-color: $app-primary-color;
401
+ border-color: $app-primary-color;
402
+ }
403
+ }
404
+
405
+ .icon {
406
+ right: 0px;
407
+ position: absolute;
408
+ top: 10px;
409
+ }
410
+
411
+ .icon:hover {
412
+ cursor: pointer;
413
+ }
414
+
415
+ :deep(.popover-origin-help.el-popover) {
416
+ text-transform: none !important; // need to overide the tooltip text transform
417
+ border: 1px solid $app-primary-color;
418
+ .el-popper__arrow {
419
+ &:before {
420
+ border-color: $app-primary-color;
421
+ background-color: #ffffff;
422
+ }
423
+ }
424
+ }
425
+
426
+ .info {
427
+ transform: rotate(180deg);
428
+ color: #8300bf;
429
+ margin-left: 8px;
430
+ }
431
+
432
+ .seperator {
433
+ width: 90%;
434
+ height: 1px;
435
+ background-color: #bfbec2;
436
+ }
437
+
438
+ .hide {
439
+ color: $app-primary-color;
440
+ cursor: pointer;
441
+ margin-right: 6px;
442
+ margin-top: 3px;
443
+ }
444
+
445
+ .slide-fade-enter-active {
446
+ transition: opacity 0.5s, transform 0.5s;
447
+ }
448
+ .slide-fade-leave-active {
449
+ transition: opacity 0.2s, transform 0.2s;
450
+ }
451
+ .slide-fade-enter, .slide-fade-leave-to /* .slide-fade-leave-active in <2.1.8 */ {
452
+ opacity: 0;
453
+ transform: translateY(-8px);
454
+ }
455
+
456
+ .main {
457
+ font-size: 14px;
458
+ text-align: left;
459
+ line-height: 1.5em;
460
+ font-family: Asap, sans-serif, Helvetica;
461
+ font-weight: 400;
462
+ /* outline: thin red solid; */
463
+ overflow-y: auto;
464
+ scrollbar-width: thin;
465
+ min-width: 16rem;
466
+ background-color: #f7faff;
467
+ height: 100%;
468
+ border-left: 1px solid var(--el-border-color);
469
+ border-top: 1px solid var(--el-border-color);
470
+ }
471
+
472
+ .attribute-title-container {
473
+ margin-bottom: 0.5em;
474
+ }
475
+
476
+ .attribute-title {
477
+ font-size: 16px;
478
+ font-weight: 600;
479
+ /* font-weight: bold; */
480
+ text-transform: uppercase;
481
+ }
482
+
483
+ .attribute-content {
484
+ font-size: 14px;
485
+ font-weight: 500;
486
+
487
+ &:last-of-type {
488
+ margin-bottom: 0.5em;
489
+ }
490
+ }
491
+
492
+ .popover-container {
493
+ height: 100%;
494
+ width: 100%;
495
+ }
496
+
497
+ .main {
498
+ .el-button.is-round {
499
+ border-radius: 4px;
500
+ padding: 9px 20px 10px 20px;
501
+ display: flex;
502
+ height: 36px;
503
+ }
504
+ }
505
+
506
+ .button {
507
+ margin-left: 0px !important;
508
+ margin-top: 0px !important;
509
+ font-size: 14px !important;
510
+ background-color: $app-primary-color;
511
+ color: #fff;
512
+ & + .button {
513
+ margin-top: 10px !important;
514
+ }
515
+ &:hover {
516
+ color: #fff !important;
517
+ background: #ac76c5 !important;
518
+ border: 1px solid #ac76c5 !important;
519
+ }
520
+ }
521
+
522
+ .tooltip-container {
523
+ &::after,
524
+ &::before {
525
+ content: '';
526
+ display: block;
527
+ position: absolute;
528
+ width: 0;
529
+ height: 0;
530
+ border-style: solid;
531
+ flex-shrink: 0;
532
+ }
533
+ .tooltip {
534
+ &::after {
535
+ display: none;
536
+ }
537
+ &::before {
538
+ display: none;
539
+ }
540
+ }
541
+ }
542
+
543
+ .maplibregl-popup-anchor-bottom {
544
+ .tooltip-container {
545
+ &::after,
546
+ &::before {
547
+ top: 100%;
548
+ border-width: 12px;
549
+ }
550
+ &::after {
551
+ margin-top: -1px;
552
+ border-color: rgb(255, 255, 255) transparent transparent transparent;
553
+ }
554
+ &::before {
555
+ margin: 0 auto;
556
+ border-color: $app-primary-color transparent transparent transparent;
557
+ }
558
+ }
559
+ }
560
+
561
+ .maplibregl-popup-anchor-top {
562
+ .tooltip-container {
563
+ &::after,
564
+ &::before {
565
+ top: -24px;
566
+ border-width: 12px;
567
+ }
568
+ &::after {
569
+ margin-top: 1px;
570
+ border-color: transparent transparent rgb(255, 255, 255) transparent;
571
+ }
572
+ &::before {
573
+ margin: 0 auto;
574
+ border-color: transparent transparent $app-primary-color transparent;
575
+ }
576
+ }
577
+ }
578
+
579
+ .content-container {
580
+ flex: 1 1 100%;
581
+ padding: 1rem;
582
+ box-sizing: border-box;
583
+
584
+ .block {
585
+ padding-top: 0.5em;
586
+
587
+ + .block {
588
+ margin-top: 1rem;
589
+ }
590
+ }
591
+
592
+ .connectivity-info-title ~ & {
593
+ padding-top: 0;
594
+ }
595
+ }
596
+
597
+ .scrollbar::-webkit-scrollbar-track {
598
+ border-radius: 10px;
599
+ background-color: #f5f5f5;
600
+ }
601
+
602
+ .scrollbar::-webkit-scrollbar {
603
+ width: 12px;
604
+ right: -12px;
605
+ background-color: #f5f5f5;
606
+ }
607
+
608
+ .scrollbar::-webkit-scrollbar-thumb {
609
+ border-radius: 4px;
610
+ box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.06);
611
+ background-color: #979797;
612
+ }
613
+
614
+ /* Fix for chrome bug where under triangle pops up above one on top of it */
615
+ .selector:not(*:root),
616
+ .tooltip-container::after {
617
+ top: 99.4%;
618
+ }
619
+ </style>