@abi-software/flatmapvuer 1.17.1-demo.0 → 1.18.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.
@@ -15,6 +15,7 @@
15
15
  <template #reference>
16
16
  <el-select
17
17
  id="flatmap-select"
18
+ ref="speciesSelect"
18
19
  :teleported="false"
19
20
  v-model="activeSpecies"
20
21
  placeholder="Select"
@@ -22,20 +23,64 @@
22
23
  popper-class="flatmap-dropdown"
23
24
  @change="setSpecies"
24
25
  >
25
- <el-option
26
- v-for="(item, key) in speciesList"
27
- :key="key"
28
- :label="key"
29
- :value="key"
30
- >
31
- <span class="select-box-icon">
32
- <i :class="item.iconClass"></i>
26
+ <el-option v-for="(item, key) in speciesList" :key="key" :label="key" :value="key">
27
+ <span class="option-label">
28
+ <el-tooltip
29
+ v-if="activeSpecies !== key"
30
+ :content="`Change species to ${key}`"
31
+ placement="top"
32
+ effect="light"
33
+ :show-after="200"
34
+ popper-class="flatmap-species-option-tooltip"
35
+ >
36
+ <span class="option-title">
37
+ <span class="select-box-icon">
38
+ <i :class="item.iconClass"></i>
39
+ </span>
40
+ {{ key }}
41
+ </span>
42
+ </el-tooltip>
43
+ <span v-else class="option-title active-species">
44
+ <span class="select-box-icon">
45
+ <i :class="item.iconClass"></i>
46
+ </span>
47
+ {{ key }}
48
+ </span>
49
+ <el-tooltip
50
+ v-if="enableOpenMapUI"
51
+ :content="`Open ${key} in a new view`"
52
+ placement="top"
53
+ effect="light"
54
+ :show-after="200"
55
+ popper-class="flatmap-open-new-view-tooltip"
56
+ >
57
+ <button
58
+ type="button"
59
+ class="open-new-view-button"
60
+ :aria-label="`Open ${key} in a new view`"
61
+ @click.stop="openSpeciesInNewView(key)"
62
+ >
63
+ <svg
64
+ viewBox="0 0 24 24"
65
+ width="14"
66
+ height="14"
67
+ fill="none"
68
+ stroke="currentColor"
69
+ stroke-width="2"
70
+ stroke-linecap="round"
71
+ stroke-linejoin="round"
72
+ aria-hidden="true"
73
+ >
74
+ <rect x="8" y="8" width="13" height="13" rx="2" />
75
+ <path d="M16 8V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h3" />
76
+ <path d="M14.5 11.5v6M11.5 14.5h6" />
77
+ </svg>
78
+ </button>
79
+ </el-tooltip>
33
80
  </span>
34
- {{ key }}
35
81
  </el-option>
36
82
  </el-select>
37
83
  </template>
38
-
39
84
  </el-popover>
40
85
  </div>
41
86
  <!--
@@ -44,6 +89,13 @@
44
89
  @event open-map
45
90
  @arg {Object} `$event`
46
91
  -->
92
+ <!--
93
+ This event is emitted when the user chooses to open a species
94
+ in a new view/panel from the species select, instead of switching
95
+ the currently displayed species.
96
+ @event open-map-species
97
+ @arg {String} `species`
98
+ -->
47
99
  <FlatmapVuer
48
100
  v-for="(item, key) in speciesList"
49
101
  :key="key"
@@ -83,7 +135,7 @@
83
135
  @shown-tooltip="onTooltipShown"
84
136
  @shown-map-tooltip="onMapTooltipShown"
85
137
  :renderAtMounted="renderAtMounted"
86
- :render="render && (activeSpecies == key)"
138
+ :render="render && activeSpecies == key"
87
139
  :displayMinimap="displayMinimap"
88
140
  :showStarInLegend="showStarInLegend"
89
141
  style="height: 100%"
@@ -103,18 +155,10 @@
103
155
  </template>
104
156
 
105
157
  <script>
106
- /* eslint-disable no-alert, no-console */
107
- import { markRaw } from 'vue'
108
- import EventBus from './EventBus'
109
- import FlatmapVuer from './FlatmapVuer.vue'
110
- import flatmap from '../services/flatmapLoader.js'
111
- import {
112
- ElCol as Col,
113
- ElOption as Option,
114
- ElSelect as Select,
115
- ElRow as Row,
116
- ElPopover as Popover,
117
- } from 'element-plus'
158
+ import { markRaw } from 'vue';
159
+ import EventBus from './EventBus';
160
+ import FlatmapVuer from './FlatmapVuer.vue';
161
+ import flatmap from '../services/flatmapLoader.js';
118
162
 
119
163
  const TAXON_UUID = {
120
164
  'NCBITaxon:10114': '01fedbf9-d783-509c-a10c-827941ab13da',
@@ -122,7 +166,7 @@ const TAXON_UUID = {
122
166
  'NCBITaxon:9606': '42ed6323-f645-5fbe-bada-9581819cf689',
123
167
  'NCBITaxon:10090': '25285fab-48a0-5620-a6a0-f9a0374837d5',
124
168
  'NCBITaxon:9685': '73060497-46a6-52bf-b975-cac511c127cb',
125
- }
169
+ };
126
170
 
127
171
  /**
128
172
  * A vue component to show a flatmap from the list of multiple flatmap data.
@@ -130,21 +174,16 @@ const TAXON_UUID = {
130
174
  export default {
131
175
  name: 'MultiFlatmapVuer',
132
176
  components: {
133
- Col,
134
- Row,
135
- Option,
136
- Select,
137
- Popover,
138
177
  FlatmapVuer,
139
178
  },
140
179
  created: function () {
141
180
  this.loadMapManager();
142
181
  },
143
182
  mounted: function () {
144
- this.initialise()
183
+ this.initialise();
145
184
  EventBus.on('onActionClick', (action) => {
146
- this.resourceSelected(action)
147
- })
185
+ this.resourceSelected(action);
186
+ });
148
187
  EventBus.on('open-pubmed-url', (url) => {
149
188
  /**
150
189
  * This event is emitted when the user clicks
@@ -166,12 +205,12 @@ export default {
166
205
  return new Promise((resolve) => {
167
206
  if (this.requireInitialisation) {
168
207
  //It has not been initialised yet
169
- this.requireInitialisation = false
208
+ this.requireInitialisation = false;
170
209
  const controller = new AbortController();
171
210
  const signal = controller.signal;
172
211
  const timeoutId = setTimeout(() => controller.abort(), 5000);
173
212
 
174
- fetch(this.flatmapAPI, {signal})
213
+ fetch(this.flatmapAPI, { signal })
175
214
  .then((response) => {
176
215
  if (!response.ok) {
177
216
  // HTTP-level errors
@@ -181,7 +220,7 @@ export default {
181
220
  this.multiflatmapError['messages'] = [
182
221
  `Sorry, the component could not be loaded because the specified
183
222
  flatmap API endpoint is incorrect. Please check the endpoint URL
184
- or contact support if the problem persists.`
223
+ or contact support if the problem persists.`,
185
224
  ];
186
225
  this.initialised = true;
187
226
  resolve();
@@ -191,7 +230,7 @@ export default {
191
230
  }
192
231
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
193
232
  }
194
- return response.json()
233
+ return response.json();
195
234
  })
196
235
  .then((data) => {
197
236
  // Application-level 404 in a 200 response
@@ -202,7 +241,7 @@ export default {
202
241
  this.multiflatmapError['messages'] = [
203
242
  `Sorry, the component could not be loaded because the specified
204
243
  flatmap API endpoint is incorrect. Please check the endpoint URL
205
- or contact support if the problem persists.`
244
+ or contact support if the problem persists.`,
206
245
  ];
207
246
 
208
247
  this.initialised = true;
@@ -213,87 +252,79 @@ export default {
213
252
  //Check each key in the provided availableSpecies against the one
214
253
  Object.keys(this.availableSpecies).forEach((key) => {
215
254
  // FIrst look through the uuid
216
- const uuid = this.availableSpecies[key].uuid
255
+ const uuid = this.availableSpecies[key].uuid;
217
256
  if (uuid && data.length && data.map((e) => e.uuid).indexOf(uuid) > 0) {
218
- this.speciesList[key] = this.availableSpecies[key]
257
+ this.speciesList[key] = this.availableSpecies[key];
219
258
  } else {
220
259
  for (let i = 0; i < data.length; i++) {
221
260
  if (this.availableSpecies[key].taxo === data[i].taxon) {
222
261
  if (this.availableSpecies[key].biologicalSex) {
223
262
  if (
224
263
  data[i].biologicalSex &&
225
- data[i].biologicalSex ===
226
- this.availableSpecies[key].biologicalSex
264
+ data[i].biologicalSex === this.availableSpecies[key].biologicalSex
227
265
  ) {
228
- this.speciesList[key] = this.availableSpecies[key]
229
- break
266
+ this.speciesList[key] = this.availableSpecies[key];
267
+ break;
230
268
  }
231
269
  } else {
232
- this.speciesList[key] = this.availableSpecies[key]
233
- break
270
+ this.speciesList[key] = this.availableSpecies[key];
271
+ break;
234
272
  }
235
273
  }
236
274
  }
237
275
  }
238
- })
276
+ });
239
277
  //Use the state species if it does not have any other species information
240
- let species = this.initial
278
+ let species = this.initial;
241
279
  if (this.state) {
242
- const mapState = this.state.state
243
- if (
244
- (!mapState || (!mapState.uuid && !mapState.entry)) &&
245
- this.state.species
246
- )
247
- species = this.state.species
248
- else species = undefined
280
+ const mapState = this.state.state;
281
+ if ((!mapState || (!mapState.uuid && !mapState.entry)) && this.state.species)
282
+ species = this.state.species;
283
+ else species = undefined;
249
284
  }
250
285
  if (species) {
251
286
  //No state resuming, set the current flatmap to {this.initial}
252
287
  if (species && this.speciesList[species] !== undefined) {
253
- this.activeSpecies = species
288
+ this.activeSpecies = species;
254
289
  } else {
255
- this.activeSpecies = Object.keys(this.speciesList)[0]
290
+ this.activeSpecies = Object.keys(this.speciesList)[0];
256
291
  }
257
- this.setSpecies(
258
- this.activeSpecies,
259
- this.state ? this.state.state : undefined,
260
- 5
261
- )
292
+ this.setSpecies(this.activeSpecies, this.state ? this.state.state : undefined, 5);
262
293
  }
263
- this.initialised = true
264
- resolve()
294
+ this.initialised = true;
295
+ resolve();
265
296
  //Resolve all other promises resolve in the list
266
297
  this.resolveList.forEach((other) => {
267
- other()
268
- })
298
+ other();
299
+ });
269
300
  })
270
301
  .catch((error) => {
271
302
  if (error && error.handled) return;
272
- console.error('Error fetching flatmap:', error)
303
+ console.error('Error fetching flatmap:', error);
273
304
  this.initialised = true;
274
305
  this.multiflatmapError = {};
275
306
  this.multiflatmapError['title'] = 'MultiFlatmap Error!';
276
307
  this.multiflatmapError['messages'] = [
277
308
  `Sorry, the component could not be loaded due to an unexpected error.
278
- Please try again later or contact support if the problem persists.`
309
+ Please try again later or contact support if the problem persists.`,
279
310
  ];
280
- resolve()
311
+ resolve();
281
312
  //Resolve all other promises resolve in the list
282
313
  this.resolveList.forEach((other) => {
283
- other()
284
- })
314
+ other();
315
+ });
285
316
  })
286
317
  .finally(() => {
287
318
  clearTimeout(timeoutId);
288
319
  });
289
320
  } else if (this.initialised) {
290
321
  //resolve as it has been initialised
291
- resolve()
322
+ resolve();
292
323
  } else {
293
324
  //resolve when the async initialisation is finished
294
- this.resolveList.push(resolve)
325
+ this.resolveList.push(resolve);
295
326
  }
296
- })
327
+ });
297
328
  },
298
329
  /**
299
330
  * Function to load `mapManager` to create flatmap.
@@ -303,7 +334,9 @@ export default {
303
334
  if (this.mapManager) {
304
335
  this.mapManagerRef = this.mapManager;
305
336
  } else {
306
- this.mapManagerRef = markRaw(new flatmap.MapViewer(this.flatmapAPI, { container: undefined }));
337
+ this.mapManagerRef = markRaw(
338
+ new flatmap.MapViewer(this.flatmapAPI, { container: undefined }),
339
+ );
307
340
  /**
308
341
  * The event emitted after a new mapManager is loaded.
309
342
  * This mapManager can be used to create new flatmaps.
@@ -317,23 +350,23 @@ export default {
317
350
  * Function to emit ``resource-selected`` event with provided ``resource``.
318
351
  * @arg {Object} `action`
319
352
  */
320
- resourceSelected: function (action) {
353
+ resourceSelected: function (action) {
321
354
  /**
322
355
  * This event is emitted by ``resourceSelected`` method.
323
356
  */
324
- this.$emit('resource-selected', action)
357
+ this.$emit('resource-selected', action);
325
358
  },
326
359
  /**
327
360
  * @public
328
361
  * Function to emit ``context-restored`` event after the flatmap is restored.
329
362
  * @arg {Object} `component`
330
363
  */
331
- onContextRestored: function (component) {
364
+ onContextRestored: function (component) {
332
365
  /**
333
366
  * This event is emitted by ``ContextRestore`` method after the flatmap is restored.
334
367
  * @arg component
335
368
  */
336
- this.$emit('context-restored', component)
369
+ this.$emit('context-restored', component);
337
370
  },
338
371
  /**
339
372
  * @public
@@ -345,14 +378,30 @@ export default {
345
378
  * This event is emitted by ``FlatmapReady`` method after the flatmap is loaded.
346
379
  * @arg component
347
380
  */
348
- this.$emit('ready', component)
381
+ this.$emit('ready', component);
349
382
  },
350
383
  /**
351
384
  * @public
352
385
  * Function to get the current active map.
353
386
  */
354
387
  getCurrentFlatmap: function () {
355
- return this.$refs[this.activeSpecies][0]
388
+ return this.$refs[this.activeSpecies][0];
389
+ },
390
+ /**
391
+ * @public
392
+ * Function to request opening the given species in a new view/panel,
393
+ * leaving the currently displayed species unchanged.
394
+ * @arg {String} `species`
395
+ */
396
+ openSpeciesInNewView: function (species) {
397
+ // Close the dropdown as the species opens in another view
398
+ this.$refs.speciesSelect?.blur();
399
+ /**
400
+ * This event is emitted when the user chooses to open a species
401
+ * in a new view/panel instead of switching the current one.
402
+ * @arg species
403
+ */
404
+ this.$emit('open-map-species', species);
356
405
  },
357
406
  /**
358
407
  * @public
@@ -365,7 +414,7 @@ export default {
365
414
  * The event emitted by ``panZoomCallback`` method.
366
415
  * @arg payload
367
416
  */
368
- this.$emit('pan-zoom-callback', payload)
417
+ this.$emit('pan-zoom-callback', payload);
369
418
  },
370
419
  onAnnotationClose: function () {
371
420
  this.$emit('annotation-close');
@@ -399,8 +448,8 @@ export default {
399
448
  * @arg {Object} `options`
400
449
  */
401
450
  showPopup: function (featureId, node, options) {
402
- let map = this.getCurrentFlatmap()
403
- map.showPopup(featureId, node, options)
451
+ let map = this.getCurrentFlatmap();
452
+ map.showPopup(featureId, node, options);
404
453
  },
405
454
  /**
406
455
  * @public
@@ -410,8 +459,8 @@ export default {
410
459
  * @arg {Object} `options`
411
460
  */
412
461
  showMarkerPopup: function (featureId, node, options) {
413
- let map = this.getCurrentFlatmap()
414
- map.showMarkerPopup(featureId, node, options)
462
+ let map = this.getCurrentFlatmap();
463
+ map.showMarkerPopup(featureId, node, options);
415
464
  },
416
465
  /**
417
466
  * @public
@@ -424,20 +473,20 @@ export default {
424
473
  */
425
474
  setSpecies: function (species, state, numberOfRetry) {
426
475
  if (this.$refs && species in this.$refs) {
427
- this.activeSpecies = species
428
- this.$refs[this.activeSpecies][0].createFlatmap(state)
476
+ this.activeSpecies = species;
477
+ this.$refs[this.activeSpecies][0].createFlatmap(state);
429
478
  /**
430
479
  * This event is emitted by ``setSpecies`` method.
431
480
  * Emitted on first load and when user changes species.
432
481
  * @arg activeSpecies
433
482
  */
434
- this.$emit('flatmapChanged', this.activeSpecies)
483
+ this.$emit('flatmapChanged', this.activeSpecies);
435
484
  } else if (numberOfRetry) {
436
- const retry = numberOfRetry - 1
485
+ const retry = numberOfRetry - 1;
437
486
  if (retry >= 0) {
438
487
  this.$nextTick(() => {
439
- this.setSpecies(species, state, retry)
440
- })
488
+ this.setSpecies(species, state, retry);
489
+ });
441
490
  }
442
491
  }
443
492
  },
@@ -449,16 +498,16 @@ export default {
449
498
  * @private
450
499
  */
451
500
  viewLatestMap: function (state) {
452
- const keys = Object.keys(this.speciesList)
501
+ const keys = Object.keys(this.speciesList);
453
502
  for (let i = 0; i < keys.length; i++) {
454
- const species = this.speciesList[keys[i]]
503
+ const species = this.speciesList[keys[i]];
455
504
  if (
456
505
  !species.isLegacy &&
457
506
  species.taxo === state.entry &&
458
507
  species.biologicalSex === state.biologicalSex
459
508
  ) {
460
- this.setSpecies(keys[i], state, 0)
461
- return
509
+ this.setSpecies(keys[i], state, 0);
510
+ return;
462
511
  }
463
512
  }
464
513
  },
@@ -471,16 +520,16 @@ export default {
471
520
  */
472
521
  createLegacyEntry: function (state, taxo, uuid) {
473
522
  if (uuid && taxo) {
474
- let name = 'Legacy'
523
+ let name = 'Legacy';
475
524
  if (state.species) {
476
- if (state.species.slice(0, 6) === 'Legacy') name = state.species
477
- else name = name + ` ${state.species}`
525
+ if (state.species.slice(0, 6) === 'Legacy') name = state.species;
526
+ else name = name + ` ${state.species}`;
478
527
  }
479
528
  this.speciesList[name] = {
480
529
  taxo: taxo,
481
530
  isLegacy: true,
482
531
  displayWarning: true,
483
- }
532
+ };
484
533
  return {
485
534
  species: name,
486
535
  state: {
@@ -489,7 +538,7 @@ export default {
489
538
  viewport: state.state.viewport,
490
539
  searchTerm: state.state.searchTerm,
491
540
  },
492
- }
541
+ };
493
542
  }
494
543
  },
495
544
  /**
@@ -502,52 +551,40 @@ export default {
502
551
  updateState: function (state) {
503
552
  return new Promise((resolve) => {
504
553
  if (state && state.state) {
505
- const mapState = state.state
554
+ const mapState = state.state;
506
555
  //uuid is not in the state, this is a legacy map
507
556
  if (!mapState.uuid) {
508
557
  if (mapState.entry) {
509
- const uuid =
510
- mapState.entry in TAXON_UUID
511
- ? TAXON_UUID[mapState.entry]
512
- : undefined
513
- const newState = this.createLegacyEntry(
514
- state,
515
- mapState.entry,
516
- uuid
517
- )
518
- resolve(newState ? newState : state)
558
+ const uuid = mapState.entry in TAXON_UUID ? TAXON_UUID[mapState.entry] : undefined;
559
+ const newState = this.createLegacyEntry(state, mapState.entry, uuid);
560
+ resolve(newState ? newState : state);
519
561
  }
520
562
  } else if (mapState.entry) {
521
563
  //uuid is in the state but should be checked if it is the latest map
522
564
  //for that taxon
523
565
  return new Promise(() => {
524
566
  //mapManager.findMap_ is an async function so we need to wrap this with a promise
525
- const identifier = { taxon: mapState.entry }
526
- if (mapState.biologicalSex)
527
- identifier['biologicalSex'] = mapState.biologicalSex
567
+ const identifier = { taxon: mapState.entry };
568
+ if (mapState.biologicalSex) identifier['biologicalSex'] = mapState.biologicalSex;
528
569
  this.mapManagerRef
529
570
  .findMap(identifier)
530
571
  .then((map) => {
531
572
  if (map.uuid !== mapState.uuid) {
532
- return this.createLegacyEntry(
533
- state,
534
- mapState.entry,
535
- mapState.uuid
536
- )
573
+ return this.createLegacyEntry(state, mapState.entry, mapState.uuid);
537
574
  }
538
575
  })
539
576
  .then((newState) => {
540
- resolve(newState ? newState : state)
577
+ resolve(newState ? newState : state);
541
578
  })
542
579
  .catch(() => {
543
- resolve(state)
544
- })
545
- })
580
+ resolve(state);
581
+ });
582
+ });
546
583
  }
547
584
  //Create a new state and add the legacy map to the select
548
585
  }
549
- resolve(state)
550
- })
586
+ resolve(state);
587
+ });
551
588
  },
552
589
  /**
553
590
  * @public
@@ -558,10 +595,10 @@ export default {
558
595
  let state = {
559
596
  species: this.activeSpecies,
560
597
  state: undefined,
561
- }
562
- let map = this.getCurrentFlatmap()
563
- state.state = map.getState()
564
- return state
598
+ };
599
+ let map = this.getCurrentFlatmap();
600
+ state.state = map.getState();
601
+ return state;
565
602
  },
566
603
  /**
567
604
  * @public
@@ -577,17 +614,14 @@ export default {
577
614
  //Update state if required
578
615
  this.updateState(state).then((currentState) => {
579
616
  this.initialise().then(() => {
580
- if (
581
- currentState.species &&
582
- currentState.species !== this.activeSpecies
583
- ) {
584
- this.setSpecies(currentState.species, currentState.state, 5)
617
+ if (currentState.species && currentState.species !== this.activeSpecies) {
618
+ this.setSpecies(currentState.species, currentState.state, 5);
585
619
  } else if (currentState.state) {
586
- let map = this.getCurrentFlatmap()
587
- map.setState(currentState.state)
620
+ let map = this.getCurrentFlatmap();
621
+ map.setState(currentState.state);
588
622
  }
589
- })
590
- })
623
+ });
624
+ });
591
625
  }
592
626
  },
593
627
  /**
@@ -596,10 +630,7 @@ export default {
596
630
  * @arg {Number} `index`
597
631
  */
598
632
  activateTooltipByIndex: function (index) {
599
- return (
600
- index === this.helpModeActiveItem
601
- && this.helpMode
602
- );
633
+ return index === this.helpModeActiveItem && this.helpMode;
603
634
  },
604
635
  /**
605
636
  * @public
@@ -637,9 +668,9 @@ export default {
637
668
  * @arg {String} `modeName`
638
669
  */
639
670
  changeViewingMode: function (modeName) {
640
- let map = this.getCurrentFlatmap()
671
+ let map = this.getCurrentFlatmap();
641
672
  if (map) {
642
- map.changeViewingMode(modeName)
673
+ map.changeViewingMode(modeName);
643
674
  }
644
675
  },
645
676
  setConnectionType: function (type) {
@@ -812,7 +843,7 @@ export default {
812
843
  iconClass: 'mapicon-icon_cat',
813
844
  displayWarning: true,
814
845
  },
815
- }
846
+ };
816
847
  },
817
848
  },
818
849
  /**
@@ -861,7 +892,7 @@ export default {
861
892
  /**
862
893
  * The option to show connectivity information in sidebar
863
894
  */
864
- annotationSidebar: {
895
+ annotationSidebar: {
865
896
  type: Boolean,
866
897
  default: false,
867
898
  },
@@ -893,7 +924,7 @@ export default {
893
924
  externalLegends: {
894
925
  type: Array,
895
926
  default: function () {
896
- return []
927
+ return [];
897
928
  },
898
929
  },
899
930
  /**
@@ -914,12 +945,12 @@ export default {
914
945
  initialised: false,
915
946
  mapManagerRef: undefined,
916
947
  multiflatmapError: null,
917
- }
948
+ };
918
949
  },
919
950
  watch: {
920
951
  state: {
921
952
  handler: function (state) {
922
- this.setState(state)
953
+ this.setState(state);
923
954
  },
924
955
  immediate: true,
925
956
  deep: true,
@@ -927,12 +958,12 @@ export default {
927
958
  activeSpecies: {
928
959
  handler: function (value, oldValue) {
929
960
  if (oldValue) {
930
- this.$refs[oldValue][0].forceContextLoss()
961
+ this.$refs[oldValue][0].forceContextLoss();
931
962
  }
932
- }
933
- }
963
+ },
964
+ },
934
965
  },
935
- }
966
+ };
936
967
  </script>
937
968
 
938
969
  <style lang="scss" scoped>
@@ -989,7 +1020,7 @@ export default {
989
1020
  width: fit-content;
990
1021
  }
991
1022
  .el-input {
992
- .el-input__wrapper{
1023
+ .el-input__wrapper {
993
1024
  &is-focus,
994
1025
  &:focus {
995
1026
  border: 1px solid $app-primary-color;
@@ -1006,11 +1037,65 @@ export default {
1006
1037
  }
1007
1038
  }
1008
1039
 
1009
- .flatmap-dropdown {
1010
- min-width: 160px !important;
1040
+ .option-label {
1041
+ display: inline-flex;
1042
+ align-items: center;
1043
+ gap: 16px;
1044
+ width: 100%;
1045
+ }
1046
+
1047
+ .option-title {
1048
+ flex: 1;
1049
+ min-width: 0;
1050
+ padding: 0 8px;
1051
+ cursor: pointer;
1052
+
1053
+ &.active-species {
1054
+ cursor: default;
1055
+ }
1056
+ }
1057
+
1058
+ .open-new-view-button {
1059
+ flex-shrink: 0;
1060
+ margin-left: auto;
1061
+ display: inline-flex;
1062
+ align-items: center;
1063
+ justify-content: center;
1064
+ width: 24px;
1065
+ height: 24px;
1066
+ padding: 0;
1067
+ margin-right: 8px;
1068
+ border: 1px solid transparent;
1069
+ border-radius: 4px;
1070
+ background-color: transparent;
1071
+ color: #909399;
1072
+ cursor: pointer;
1073
+ transition:
1074
+ color 0.2s ease,
1075
+ background-color 0.2s ease,
1076
+ border-color 0.2s ease;
1077
+
1078
+ &:hover,
1079
+ &:focus-visible {
1080
+ color: $app-primary-color;
1081
+ background-color: #f3ecf6;
1082
+ border-color: $app-primary-color;
1083
+ outline: none;
1084
+ }
1085
+ }
1086
+
1087
+ :deep(.flatmap-dropdown) {
1011
1088
  .el-select-dropdown__item {
1012
1089
  white-space: nowrap;
1013
1090
  text-align: left;
1091
+ padding: 0;
1092
+
1093
+ &.is-hovering,
1094
+ &:hover {
1095
+ color: $app-primary-color;
1096
+ cursor: default;
1097
+ }
1098
+
1014
1099
  &.selected {
1015
1100
  color: $app-primary-color;
1016
1101
  font-weight: normal;
@@ -1043,9 +1128,23 @@ export default {
1043
1128
  </style>
1044
1129
 
1045
1130
  <style lang="scss">
1046
-
1047
1131
  .multi-container {
1048
- --el-color-primary: #8300BF;
1132
+ --el-color-primary: #8300bf;
1049
1133
  }
1050
1134
 
1135
+ .el-popper.flatmap-open-new-view-tooltip,
1136
+ .el-popper.flatmap-species-option-tooltip {
1137
+ padding: 6px 8px;
1138
+ font-size: 12px;
1139
+ color: rgb(48, 49, 51);
1140
+ background-color: #f3ecf6;
1141
+ border: 1px solid $app-primary-color;
1142
+ white-space: nowrap;
1143
+ font-family: $font-family;
1144
+
1145
+ .el-popper__arrow::before {
1146
+ background-color: #f3ecf6;
1147
+ border-color: $app-primary-color;
1148
+ }
1149
+ }
1051
1150
  </style>