@abi-software/map-side-bar 2.17.1-demo.1 → 2.19.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 +5906 -7001
  5. package/dist/map-side-bar.umd.cjs +62 -65
  6. package/dist/style.css +1 -1
  7. package/eslint.config.js +44 -9
  8. package/package.json +12 -5
  9. package/reporter-config.json +1 -1
  10. package/src/App.vue +80 -86
  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/ConnectivityCard.vue +22 -19
  20. package/src/components/ConnectivityExplorer.vue +107 -128
  21. package/src/components/ConnectivityInfo.vue +169 -128
  22. package/src/components/ContributorItem.vue +15 -11
  23. package/src/components/DatasetCard.vue +166 -201
  24. package/src/components/DatasetExplorer.vue +160 -201
  25. package/src/components/ImageGallery.vue +35 -36
  26. package/src/components/SearchFilters.vue +381 -408
  27. package/src/components/SearchHistory.vue +75 -91
  28. package/src/components/SideBar.vue +86 -193
  29. package/src/components/Tabs.vue +16 -30
  30. package/src/components/index.js +3 -5
  31. package/src/components/species-map.js +7 -7
  32. package/src/components.d.ts +0 -3
  33. package/src/exampleConnectivityInput.js +310 -318
  34. package/src/main.js +6 -6
  35. package/src/mixins/S3Bucket.vue +10 -13
  36. package/vite.config.js +62 -61
  37. package/vuese-generator.js +47 -55
  38. package/src/components/CellCard.vue +0 -994
  39. package/src/components/CellCardExplorer.vue +0 -882
  40. package/src/components/icons/IconOpenExternal.vue +0 -28
  41. package/src/utils/common.js +0 -71
@@ -1,994 +0,0 @@
1
- <template>
2
- <div
3
- ref="cardElementRef"
4
- class="card"
5
- :class="{ active: isActive }"
6
- :style="cardStyleVars"
7
- >
8
- <div
9
- class="card-header"
10
- @click="openCard"
11
- >
12
- <div class="title-content">
13
- <div class="card-title">
14
- {{ cellType.preferredLabel }}
15
- </div>
16
- <div class="card-keywords">
17
- <span>{{ cellType.species }}</span>
18
- <div class="card-chips">
19
- <span
20
- v-for="somaLocation in cellType.somaLocations"
21
- class="card-chip"
22
- :key="somaLocation">
23
- {{ somaLocation }}
24
- </span>
25
- </div>
26
- <span class="source-publication-chip" v-if="cellType.sourceNomenclature">
27
- {{ cellType.sourceNomenclatureLabel }}
28
- </span>
29
- </div>
30
- <el-button
31
- v-if="isActive && (cellType.alertNotes?.length || cellType.curatorNotes?.length)"
32
- round
33
- size="small"
34
- class="alert-chip"
35
- @click.stop="showAlertMessage"
36
- >
37
- <el-icon class="alert"><el-icon-warn-triangle-filled /></el-icon>
38
- Notes
39
- </el-button>
40
- </div>
41
- <div class="title-buttons" @click.stop>
42
- <CopyToClipboard @copied="onCopied" :content="updatedCopyContent" />
43
- <el-popover
44
- width="auto"
45
- trigger="hover"
46
- :teleported="false"
47
- popper-class="popover-map-pin"
48
- >
49
- <template #reference>
50
- <el-button class="button-circle" circle @click="closeCard">
51
- <el-icon color="white">
52
- <el-icon-close />
53
- </el-icon>
54
- </el-button>
55
- </template>
56
- <span>Close</span>
57
- </el-popover>
58
- </div>
59
- </div>
60
- <div class="card-details">
61
- <div class="card-details-inner">
62
- <div v-if="cellType.entity" class="card-section">
63
- <div class="card-section-title">Entity</div>
64
- <span>{{ cellType.entity }}</span>
65
- </div>
66
- <div v-if="cellType.species" class="card-section">
67
- <div class="card-section-title">Species</div>
68
- <span>{{ cellType.species }}</span>
69
- </div>
70
- <div v-if="cellType.somaLocations?.length" class="card-section">
71
- <div class="card-section-title">Soma Location</div>
72
- <div class="card-list-items">
73
- <div
74
- v-for="location in somaLocations"
75
- class="card-list-item"
76
- :key="location.id"
77
- @mouseenter="showSomaLocation(location.name)"
78
- @mouseleave="showSomaLocation()"
79
- >
80
- <span>{{ location.name }}</span>
81
- <div class="card-list-search">
82
- <el-popover
83
- width="180"
84
- trigger="hover"
85
- :teleported="true"
86
- :append-to="cardElement"
87
- popper-class="popover-origin-help popover-search-actions"
88
- @show="onSearchPopoverShow(location.id)"
89
- @hide="onSearchPopoverHide(location.id)"
90
- >
91
- <template #reference>
92
- <el-icon
93
- class="status-search-icon"
94
- :class="{ 'is-visible': activeSearchPopoverLocationId === location.id }"
95
- >
96
- <el-icon-search />
97
- </el-icon>
98
- </template>
99
- <div class="search-action-list">
100
- <button
101
- type="button"
102
- class="search-action-button"
103
- @click="openDatasetSearch(location.name)"
104
- >
105
- Search dataset
106
- </button>
107
- <button
108
- type="button"
109
- class="search-action-button"
110
- @click="openConnectivitySearch(location.name)"
111
- >
112
- Search connectivity
113
- </button>
114
- </div>
115
- </el-popover>
116
- </div>
117
- </div>
118
- </div>
119
- </div>
120
- <div v-if="cellType.circuitRole" class="card-section">
121
- <div class="card-section-title">Circuit Role</div>
122
- <span>{{ cellType.circuitRole }}</span>
123
- </div>
124
- <div v-if="cellType.creLine" class="card-section">
125
- <div class="card-section-title">Cre Line</div>
126
- <span>{{ cellType.creLine }}</span>
127
- </div>
128
- <div v-if="formattedMarkerGenes.length" class="card-section">
129
- <div class="card-section-title">Marker Genes</div>
130
- <div class="marker-genes-list">
131
- <a
132
- v-for="markerGene in formattedMarkerGenes"
133
- :key="markerGene.key"
134
- class="marker-gene-link"
135
- :href="markerGene.uri"
136
- target="_blank"
137
- rel="noopener noreferrer"
138
- >
139
- <span>{{ markerGene.name }}</span>
140
- <sup v-if="markerGene.expression">{{ markerGene.expression }}</sup>
141
- <IconOpenExternal class="external-link-icon" />
142
- </a>
143
- </div>
144
- </div>
145
- <div v-if="cellType.fiberTypeString" class="card-section">
146
- <div class="card-section-title">Axon Phenotype</div>
147
- <div class="card-section-content">{{ cellType.fiberTypeString }}</div>
148
- </div>
149
- <div v-if="cellType.physiologyString" class="card-section">
150
- <div class="card-section-title">Physiology</div>
151
- <div class="card-section-content success">{{ cellType.physiologyString }}</div>
152
- </div>
153
- <div v-if="cellType.relatedCells?.length" class="card-section">
154
- <div class="card-section-title">Related Species Variants</div>
155
- <ul class="related-cell-list">
156
- <li v-for="relatedCell in cellType.relatedCells" :key="relatedCell">
157
- <button
158
- class="related-cell-item"
159
- @click.stop="$emit('related-cell-click', relatedCell)"
160
- title="Click to view this cell type"
161
- >
162
- {{ relatedCell.label }}
163
- </button>
164
- </li>
165
- </ul>
166
- </div>
167
- <div v-if="cellType.sourceNomenclature" class="card-section source-publication-section">
168
- <div class="card-section-title">Source Publication</div>
169
- <p>
170
- <a
171
- class="source-publication-link"
172
- :href="cellType.sourceNomenclature"
173
- target="_blank"
174
- rel="noopener noreferrer"
175
- >
176
- {{ cellType.sourceNomenclatureLabel }}
177
- <IconOpenExternal class="external-link-icon" />
178
- </a>
179
- </p>
180
- </div>
181
- <div
182
- class="card-section"
183
- v-if="cellType.alertNotes?.length || cellType.curatorNotes?.length"
184
- ref="alertElement"
185
- >
186
- <div class="card-section-title">Notes</div>
187
- <div class="alert-block">
188
- <div class="alert-block-section" v-if="cellType.alertNotes?.length">
189
- <div class="alert-block-title">Alert Notes:</div>
190
- <div v-for="note in cellType.alertNotes"
191
- v-html="formatAlertText(note)"
192
- class="alert-block-note"
193
- ></div>
194
- </div>
195
- <div class="alert-block-section" v-if="cellType.curatorNotes?.length">
196
- <div class="alert-block-title">Curator Notes:</div>
197
- <div v-for="note in cellType.curatorNotes"
198
- v-html="formatAlertText(note)"
199
- class="alert-block-note"
200
- ></div>
201
- </div>
202
- </div>
203
- </div>
204
- </div>
205
- </div>
206
- </div>
207
- </template>
208
-
209
- <script>
210
- import {
211
- ElButton as Button,
212
- ElIcon as Icon,
213
- } from 'element-plus'
214
- import { Warning as ElIconWarning } from '@element-plus/icons-vue'
215
- import {
216
- CopyToClipboard,
217
- } from '@abi-software/map-utilities';
218
- import '@abi-software/map-utilities/dist/style.css';
219
- import EventBus from './EventBus.js'
220
- import { capitalise, formatAlertText as formatAlertTextUtil, scrollToRef } from '../utils/common.js';
221
- import IconOpenExternal from './icons/IconOpenExternal.vue';
222
-
223
- const LOCATION_ID_MAP = {
224
- 'soma_tg': 'trigeminal ganglion',
225
- 'soma_drg': 'dorsal root ganglion',
226
- };
227
-
228
- export default {
229
- name: 'CellCard',
230
- components: {
231
- Button,
232
- Icon,
233
- ElIconWarning,
234
- CopyToClipboard,
235
- IconOpenExternal,
236
- },
237
- props: {
238
- cellType: {
239
- type: Object,
240
- required: true,
241
- },
242
- isActive: {
243
- type: Boolean,
244
- default: false,
245
- },
246
- },
247
- emits: ['open', 'close', 'soma-location-hovered', 'dataset-search', 'connectivity-search', 'related-cell-click'],
248
- data() {
249
- return {
250
- cardElement: null,
251
- activeSearchPopoverLocationId: null,
252
- };
253
- },
254
- mounted: function () {
255
- this.cardElement = this.$refs.cardElementRef;
256
- },
257
- computed: {
258
- cardStyleVars: function() {
259
- return {
260
- '--cell-card-source-color': this.cellType?.sourceColor || this.cellType?.color || '#8300bf',
261
- };
262
- },
263
- formattedMarkerGenes: function() {
264
- return (this.cellType?.markerGenes || [])
265
- .map((markerGene, index) => {
266
- const name = String(markerGene?.name || '').trim();
267
- const expression = String(markerGene?.expression || '').trim();
268
- const uri = this.sanitizeMarkerGeneUri(markerGene?.uri, expression);
269
-
270
- if (!name || !uri) {
271
- return null;
272
- }
273
-
274
- return {
275
- key: `${name}-${expression || 'none'}-${index}`,
276
- name,
277
- expression,
278
- uri,
279
- };
280
- })
281
- .filter(Boolean);
282
- },
283
- updatedCopyContent: function() {
284
- const {
285
- preferredLabel,
286
- entity,
287
- species,
288
- somaLocations,
289
- circuitRole,
290
- creLine,
291
- geneExpressionString,
292
- fiberTypeString,
293
- physiologyString,
294
- relatedCells,
295
- alertNotes,
296
- curatorNotes,
297
- sourceNomenclature,
298
- sourceNomenclatureLabel
299
- } = this.cellType;
300
-
301
- const contentArray = [];
302
- if (preferredLabel) {
303
- contentArray.push(`<div><strong>Cell Type:</strong> ${preferredLabel}</div>`);
304
- }
305
- if (entity) {
306
- contentArray.push(`<div><strong>Entity:</strong> ${entity}</div>`);
307
- }
308
- if (species) {
309
- contentArray.push(`<div><strong>Species:</strong> ${species}</div>`);
310
- }
311
- if (somaLocations?.length) {
312
- const items = somaLocations.map((location) => `<li>${location}</li>`).join('');
313
- contentArray.push(`<div><strong>Soma Locations:</strong><ul>${items}</ul></div>`);
314
- }
315
- if (circuitRole) {
316
- contentArray.push(`<div><strong>Circuit Role:</strong> ${circuitRole}</div>`);
317
- }
318
- if (creLine) {
319
- contentArray.push(`<div><strong>Cre Line:</strong> ${creLine}</div>`);
320
- }
321
- if (geneExpressionString) {
322
- contentArray.push(`<div><strong>Marker Genes:</strong> ${geneExpressionString}</div>`);
323
- }
324
- if (fiberTypeString) {
325
- contentArray.push(`<div><strong>Axon Phenotype:</strong> ${fiberTypeString}</div>`);
326
- }
327
- if (physiologyString) {
328
- contentArray.push(`<div><strong>Physiology:</strong> ${physiologyString}</div>`);
329
- }
330
- if (relatedCells?.length) {
331
- const relatedItems = relatedCells
332
- .map((cell) => cell?.label)
333
- .filter(Boolean)
334
- .map((label) => `<li>${label}</li>`)
335
- .join('');
336
- if (relatedItems) {
337
- contentArray.push(`<div><strong>Related Species Variants:</strong><ul>${relatedItems}</ul></div>`);
338
- }
339
- }
340
- if (sourceNomenclatureLabel) {
341
- const sourceLabel = sourceNomenclature
342
- ? `${sourceNomenclatureLabel} (<a href="${sourceNomenclature}">${sourceNomenclature}</a>)`
343
- : sourceNomenclatureLabel;
344
- contentArray.push(`<div><strong>Source Publication:</strong> ${sourceLabel}</div>`);
345
- }
346
-
347
- if (alertNotes?.length) {
348
- const alertContent = alertNotes
349
- .map((note) => formatAlertTextUtil(note))
350
- .join('\n');
351
- contentArray.push(`<div><strong>Alert Notes:</strong></div>\n${alertContent}`);
352
- }
353
-
354
- if (curatorNotes?.length) {
355
- const curatorContent = curatorNotes
356
- .map((note) => formatAlertTextUtil(note))
357
- .join('\n');
358
- contentArray.push(`<div><strong>Curator Notes:</strong></div>\n${curatorContent}`);
359
- }
360
-
361
- return contentArray.join('\n');
362
- },
363
- somaLocations: function() {
364
- const mappedLocations = this.cellType.somaLocations.map((location) => {
365
- const locationKey = Object.keys(LOCATION_ID_MAP).find((key) => LOCATION_ID_MAP[key] === location) || '';
366
- const isClustered = this.cellType.clusterAttributes?.[locationKey];
367
- if (isClustered) {
368
- return {
369
- name: capitalise(location),
370
- id: locationKey,
371
- }
372
- }
373
- return false;
374
- });
375
- return mappedLocations;
376
- },
377
- },
378
- methods: {
379
- sanitizeMarkerGeneUri: function(uri, expression = '') {
380
- let normalizedUri = String(uri || '').trim();
381
- const normalizedExpression = String(expression || '').trim();
382
-
383
- if (!normalizedUri) return '';
384
-
385
- if (normalizedExpression) {
386
- const escapedExpression = normalizedExpression.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
387
- normalizedUri = normalizedUri.replace(new RegExp(`\\s+${escapedExpression}$`, 'i'), '');
388
- }
389
-
390
- return normalizedUri.trim();
391
- },
392
- transformString: function(str) {
393
- if (!str) return '';
394
- // replace the string with ^ with <sup> and the next word with </sup>
395
- return str.replace(/\^(\w+)/g, '<sup>$1</sup>');
396
- },
397
- onCopied: function() {
398
- EventBus.emit('trackEvent', {
399
- 'event_name': `portal_maps_cell_card_copy`,
400
- 'category': this.cellType.preferredLabel || '',
401
- 'location': 'map_sidebar_cell_card',
402
- });
403
- },
404
- openCard: function() {
405
- this.$emit('open', this.cellType.id);
406
-
407
- EventBus.emit('trackEvent', {
408
- 'event_name': `portal_maps_cell_card_open`,
409
- 'category': this.cellType.id || '',
410
- 'location': 'map_sidebar_cell_card',
411
- });
412
- },
413
- closeCard: function() {
414
- this.$emit('close');
415
-
416
- EventBus.emit('trackEvent', {
417
- 'event_name': `portal_maps_cell_card_close`,
418
- 'category': this.cellType.id || '',
419
- 'location': 'map_sidebar_cell_card',
420
- });
421
- },
422
- showSomaLocation: function (name) {
423
- this.$emit('soma-location-hovered', name);
424
- },
425
- openDatasetSearch: function (query) {
426
- this.$emit('dataset-search', {
427
- species: capitalise(this.cellType?.species),
428
- location: query,
429
- });
430
- },
431
- openConnectivitySearch: function (query) {
432
- // Find the UBERON term from query value (label)
433
- const availableDataRaw = localStorage.getItem('available-name-curie-mapping');
434
- const availableData = availableDataRaw ? JSON.parse(availableDataRaw) : {};
435
- const locationCurie = Object.keys(availableData).find(
436
- (curie) => availableData[curie].toLowerCase() === query.toLowerCase()
437
- );
438
- const facets = locationCurie ? [
439
- {
440
- "facet": `[\"${locationCurie}\",[]]`,
441
- "facetPropPath": "flatmap.connectivity.source.all",
442
- "tagLabel": query,
443
- "term": "All"
444
- }
445
- ] : [];
446
- this.$emit('connectivity-search', {
447
- facets: facets,
448
- query: '',
449
- });
450
- },
451
- onSearchPopoverShow: function (locationId) {
452
- this.activeSearchPopoverLocationId = locationId;
453
- },
454
- onSearchPopoverHide: function (locationId) {
455
- if (this.activeSearchPopoverLocationId === locationId) {
456
- this.activeSearchPopoverLocationId = null;
457
- }
458
- },
459
- showAlertMessage: function () {
460
- scrollToRef(this, 'alertElement');
461
- },
462
- formatAlertText: function (text) {
463
- return formatAlertTextUtil(text);
464
- },
465
- }
466
- }
467
- </script>
468
-
469
- <style lang="scss" scoped>
470
- .card {
471
- position: relative;
472
- font-family: Asap;
473
- font-size: 14px;
474
- box-sizing: border-box;
475
-
476
- &::before {
477
- content: '';
478
- position: absolute;
479
- top: 5px;
480
- left: 5px;
481
- width: calc(100% - 15px);
482
- height: calc(100% - 10px);
483
- border: 3px solid transparent;
484
- border-radius: 5px;
485
- box-sizing: border-box;
486
- z-index: 1;
487
- }
488
-
489
- &.active::before,
490
- &:hover::before {
491
- border-color: $app-primary-color;
492
- }
493
-
494
- &:not(:first-child) {
495
- margin-top: 5px;
496
-
497
- &::after {
498
- content: '';
499
- position: absolute;
500
- top: 0px;
501
- left: 10px;
502
- width: 455px; // Same as other cards in the sidebar
503
- height: 2px; // Same as other cards in the sidebar
504
- background-color: #e4e7ed;
505
- z-index: 0;
506
- }
507
- }
508
-
509
- .card-details {
510
- display: none;
511
- }
512
-
513
- &.active {
514
- background-color: #f7faff;
515
-
516
- &::before {
517
- top: 0;
518
- left: 0;
519
- width: 100%;
520
- height: 100%;
521
- }
522
-
523
- .card-header {
524
- cursor: default;
525
-
526
- &::before {
527
- opacity: 1;
528
- }
529
-
530
- .card-title {
531
- margin: 0;
532
- line-height: 1.3em !important;
533
- font-size: 18px;
534
- font-weight: bold;
535
- color: $app-primary-color;
536
- }
537
-
538
- .card-keywords {
539
- display: none;
540
- }
541
- }
542
-
543
- .card-details {
544
- display: block;
545
- }
546
- }
547
- }
548
-
549
- .card-header {
550
- display: flex;
551
- justify-content: space-between;
552
- align-items: flex-start;
553
- cursor: pointer;
554
- position: relative;
555
-
556
- &::before {
557
- content: "";
558
- position: absolute;
559
- bottom: 7px;
560
- left: 5px;
561
- width: calc(100% - 10px);
562
- height: 1px;
563
- opacity: 0;
564
- transition: opacity 0.25s ease;
565
- }
566
- }
567
-
568
- .card-header,
569
- .card-details {
570
- position: relative;
571
- z-index: 2;
572
- }
573
-
574
- .card-header,
575
- .card-details-inner {
576
- padding: 1rem;
577
- }
578
-
579
- .title-content {
580
- display: flex;
581
- flex-direction: column;
582
- align-items: flex-start;
583
- }
584
-
585
- .card-title {
586
- margin-bottom: 0.75rem;
587
- font-weight: bold;
588
- line-height: 1.5;
589
- letter-spacing: 1.05px;
590
- display: -webkit-box;
591
- -webkit-line-clamp: 5;
592
- line-clamp: 5;
593
- -webkit-box-orient: vertical;
594
- overflow: hidden;
595
- }
596
-
597
- .card-details-inner {
598
- display: flex;
599
- flex-direction: column;
600
- gap: 1.75rem;
601
- padding-top: 0;
602
- }
603
-
604
- .card-keywords,
605
- .card-chips {
606
- display: flex;
607
- align-items: center;
608
- gap: 0.5rem;
609
-
610
- span {
611
- color: #606266;
612
- }
613
- }
614
-
615
- .card-chip {
616
- display: inline-block;
617
- padding: 2px 8px;
618
- background-color: #f0f0f0;
619
- border-radius: 12px;
620
- transition: background-color 0.2s ease;
621
-
622
- .card-details & {
623
- padding: 4px 8px;
624
- border: 1px solid #dcdcdc;
625
-
626
- }
627
- }
628
-
629
- .card-list-items {
630
- display: flex;
631
- flex-direction: column;
632
- gap: 0.25rem;
633
- box-sizing: border-box;
634
- position: relative;
635
- }
636
-
637
- .card-list-item {
638
- width: 100%;
639
- display: flex;
640
- align-items: center;
641
- justify-content: space-between;
642
- gap: 0.5rem;
643
- padding: 0.5rem;
644
- position: relative;
645
- box-sizing: border-box;
646
-
647
- &::before {
648
- content: '';
649
- position: absolute;
650
- inset: 0;
651
- transition: background-color 0.2s ease, border-color 0.2s ease;
652
- background-color: rgba($app-primary-color, 0.04);
653
- border-left: 4px solid rgba($app-primary-color, 0.16);
654
- }
655
-
656
- &:hover::before {
657
- background-color: rgba($app-primary-color, 0.07);
658
- border-left-color: rgba($app-primary-color, 0.24);
659
- }
660
-
661
- > span {
662
- line-height: 1.5em;
663
- font-weight: 500;
664
- }
665
- }
666
-
667
- .card-list-search {
668
- display: flex;
669
- gap: 0.25rem;
670
- }
671
-
672
- .status-search-icon {
673
- font-size: 16px;
674
- color: $app-primary-color;
675
- cursor: pointer;
676
- opacity: 0;
677
- transition: opacity 0.2s ease;
678
-
679
- &.is-visible {
680
- opacity: 1;
681
- }
682
-
683
- &:hover {
684
- color: #ac76c5;
685
- }
686
- }
687
-
688
- .card-list-item:hover .status-search-icon {
689
- opacity: 1;
690
- }
691
-
692
- :deep(.popover-origin-help.el-popover) {
693
- font-family: 'Asap', sans-serif;
694
- background: #f3ecf6 !important;
695
- border: 1px solid $app-primary-color !important;
696
- border-radius: 4px !important;
697
- color: #303133 !important;
698
- text-transform: none !important; // need to overide the tooltip text transform
699
- font-weight: 400;
700
-
701
- .el-popper__arrow {
702
- &:before {
703
- background: #f3ecf6 !important;
704
- border-color: $app-primary-color;
705
- background-color: #ffffff;
706
- }
707
- }
708
- }
709
-
710
- :deep(.popover-search-actions.el-popover) {
711
- padding: 6px;
712
- }
713
-
714
- .search-action-list {
715
- display: flex;
716
- flex-direction: column;
717
- gap: 4px;
718
- }
719
-
720
- .search-action-button {
721
- border: 0;
722
- width: 100%;
723
- padding: 6px 8px;
724
- text-align: left;
725
- border-radius: 4px;
726
- font-family: inherit;
727
- font-size: 12px;
728
- color: #303133;
729
- background: transparent;
730
- cursor: pointer;
731
-
732
- &:hover {
733
- background-color: rgba($app-primary-color, 0.12);
734
- color: $app-primary-color;
735
- }
736
- }
737
-
738
- .card-section {
739
- .card-section-title {
740
- font-weight: 600;
741
- }
742
-
743
- p {
744
- margin: 0;
745
- color: #606266;
746
- }
747
-
748
- ul {
749
- margin: 0;
750
- padding-left: 1rem;
751
-
752
- &.related-cell-list {
753
- list-style-type: none;
754
- padding-left: 0;
755
- }
756
-
757
- li {
758
- color: #606266;
759
- }
760
- }
761
- }
762
-
763
- .card-section {
764
- .card-section-title {
765
- display: block;
766
- margin-bottom: 0.75rem;
767
- font-size: 16px;
768
- font-weight: 600;
769
- text-transform: uppercase;
770
- }
771
- }
772
-
773
- .card-section-content {
774
- padding: 0.5rem;
775
- background-color: #f0f0f0;
776
- border-radius: 4px;
777
- border: 1px solid #dcdcdc;
778
-
779
- &.success {
780
- border-color: #b3e5b3;
781
- background-color: #f0f9eb;
782
- }
783
- }
784
-
785
- .marker-genes-list {
786
- display: flex;
787
- flex-wrap: wrap;
788
- gap: 0.5rem;
789
- }
790
-
791
- .marker-gene-link {
792
- display: inline-flex;
793
- align-items: flex-start;
794
- gap: 0.1rem;
795
- padding: 0.25rem 0.5rem;
796
- font-size: 12px;
797
- border: 1px solid $app-primary-color;
798
- border-radius: 4px;
799
- color: $app-primary-color;
800
- background-color: #f9f2fc;
801
- text-decoration: none;
802
- line-height: 1.2;
803
-
804
- &:hover {
805
- background-image: linear-gradient(rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.05));
806
- }
807
-
808
- sup {
809
- font-size: 0.75em;
810
- line-height: 1;
811
- }
812
- }
813
-
814
- .external-link-icon {
815
- display: inline-flex;
816
- align-items: center;
817
- width: 16px;
818
- height: 16px;
819
- margin-left: 2px;
820
- color: currentColor;
821
- opacity: 0.7;
822
- vertical-align: middle;
823
- }
824
-
825
- .source-publication-chip,
826
- .source-publication-link {
827
- display: inline-block;
828
- border-radius: 4px;
829
- color: white !important;
830
- text-decoration: none;
831
- background-color: var(--cell-card-source-color);
832
- }
833
-
834
- .source-publication-chip {
835
- padding: 2px 8px;
836
- font-size: 13px;
837
- }
838
-
839
- .alert-chip {
840
- margin-top: 5px;
841
- background-color: $app-primary-color;
842
- border-color: $app-primary-color;
843
- color: #fff;
844
-
845
- &:hover {
846
- color: #fff !important;
847
- background-color: #ac76c5 !important;
848
- border: 1px solid #ac76c5 !important;
849
- }
850
-
851
- :deep(> span) {
852
- gap: 2px;
853
- }
854
-
855
- .alert {
856
- width: 1rem;
857
- height: 1rem;
858
- color: inherit;
859
- margin: 0;
860
- }
861
- }
862
-
863
- .source-publication-link {
864
- padding: 4px 8px;
865
-
866
- &:hover {
867
- background-image: linear-gradient(rgba(0, 0, 0, 0.12), rgba(0, 0, 0, 0.12));
868
- }
869
- }
870
-
871
- :deep(.el-popper.popover-map-pin) {
872
- padding: 4px 10px;
873
- min-width: max-content;
874
- font-family: Asap;
875
- font-size: 12px;
876
- line-height: inherit;
877
- color: inherit;
878
- background: #f3ecf6 !important;
879
- border: 1px solid $app-primary-color;
880
-
881
- & .el-popper__arrow::before {
882
- border: 1px solid;
883
- border-color: $app-primary-color;
884
- background: #f3ecf6;
885
- }
886
- }
887
-
888
- .title-buttons {
889
- flex: 1 0 0%;
890
- max-width: 20%;
891
- flex-direction: row;
892
- justify-content: end;
893
- gap: 0.5rem;
894
- display: none;
895
-
896
- .card.active & {
897
- display: flex;
898
- }
899
-
900
- :deep(.copy-clipboard-button) {
901
- &,
902
- &:hover,
903
- &:focus {
904
- border-color: $app-primary-color !important;
905
- border-radius: 50%;
906
- }
907
-
908
- &.is-disabled {
909
- border-color: #dab3ec !important;
910
- }
911
- }
912
-
913
- .el-button + .el-button {
914
- margin-left: 0 !important;
915
- }
916
- }
917
-
918
- .button-circle {
919
- margin: 0;
920
- width: 24px !important;
921
- height: 24px !important;
922
- border: 1px solid $app-primary-color !important;
923
-
924
- &,
925
- &:hover,
926
- &:focus,
927
- &:active {
928
- background-color: $app-primary-color;
929
- border-color: $app-primary-color !important;
930
- }
931
-
932
- &.secondary {
933
- background-color: white !important;
934
- }
935
- }
936
-
937
- .alert-block {
938
- background-color: var(--el-color-warning-light-9);
939
- border: 1px dashed var(--el-color-warning);
940
- padding: 0.75rem;
941
- border-radius: 4px;
942
- display: flex;
943
- flex-direction: column;
944
- gap: 1rem;
945
-
946
- :deep(a) {
947
- color: $app-primary-color;
948
- word-break: break-all;
949
-
950
- &:hover {
951
- opacity: 0.8;
952
- }
953
- }
954
- }
955
-
956
- .alert-block-section {
957
- .alert-block-title {
958
- font-weight: 600;
959
- margin-bottom: 0.5rem;
960
- }
961
-
962
- .alert-block-note {
963
- color: #606266;
964
- padding-left: 0.5rem;
965
-
966
- + .alert-block-note {
967
- margin-top: 0.5rem;
968
- }
969
- }
970
- }
971
-
972
- .related-cell-list {
973
- li + li {
974
- margin-top: 0.5rem;
975
- }
976
- }
977
-
978
- .related-cell-item {
979
- cursor: pointer;
980
- color: $app-primary-color;
981
- background: none;
982
- border: 1px solid $app-primary-color;
983
- border-radius: 4px;
984
- padding: 2px 4px;
985
- font-family: inherit;
986
- font-size: inherit;
987
- line-height: inherit;
988
- transition: background-color 0.2s ease, border-color 0.2s ease, text-decoration-color 0.2s ease;
989
-
990
- &:hover {
991
- background-color: rgba($app-primary-color, 0.08);
992
- }
993
- }
994
- </style>