@abi-software/flatmapvuer 1.1.0-beta.3 → 1.1.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.
@@ -27,15 +27,15 @@ Please use `const` to assign meaningful names to them...
27
27
  -->
28
28
  <p
29
29
  v-if="isLegacy"
30
- @mouseover="showToolitip(6)"
31
- @mouseout="hideToolitip(6)"
30
+ @mouseover="showTooltip(6)"
31
+ @mouseout="hideTooltip(6)"
32
32
  >
33
33
  This is a legacy map, you may view the latest map instead.
34
34
  </p>
35
35
  <p
36
36
  v-else-if="isFC"
37
- @mouseover="showToolitip(6)"
38
- @mouseout="hideToolitip(6)"
37
+ @mouseover="showTooltip(6)"
38
+ @mouseout="hideTooltip(6)"
39
39
  >
40
40
  This map displays the connectivity of individual neurons.
41
41
  Specifically, those which align with (parts of) the neuron
@@ -54,7 +54,7 @@ Please use `const` to assign meaningful names to them...
54
54
  SCKAN </a
55
55
  >.
56
56
  </p>
57
- <p v-else @mouseover="showToolitip(6)" @mouseout="hideToolitip(6)">
57
+ <p v-else @mouseover="showTooltip(6)" @mouseout="hideTooltip(6)">
58
58
  This map displays the connectivity of neuron populations.
59
59
  Specifically, those from the primarily rat-based
60
60
  <a
@@ -76,8 +76,8 @@ Please use `const` to assign meaningful names to them...
76
76
  <div
77
77
  class="warning-icon"
78
78
  v-if="displayWarning"
79
- @mouseover="showToolitip(6)"
80
- @mouseout="hideToolitip(6)"
79
+ @mouseover="showTooltip(6)"
80
+ @mouseout="hideTooltip(6)"
81
81
  >
82
82
  <el-icon><el-icon-warning-filled /></el-icon>
83
83
  <template v-if="isLegacy">
@@ -100,13 +100,14 @@ Please use `const` to assign meaningful names to them...
100
100
  trigger="manual"
101
101
  popper-class="warning-popper flatmap-popper"
102
102
  :visible="hoverVisibilities[7].value"
103
+ ref="whatsNewPopover"
103
104
  >
104
105
  <template #reference>
105
106
  <div
106
107
  class="latest-changesicon"
107
108
  v-if="displayLatestChanges"
108
- @mouseover="showToolitip(7)"
109
- @mouseout="hideToolitip(7)"
109
+ @mouseover="showTooltip(7)"
110
+ @mouseout="hideTooltip(7)"
110
111
  >
111
112
  <el-icon><el-icon-warning-filled /></el-icon>
112
113
  <span class="warning-text">What's new?</span>
@@ -144,22 +145,20 @@ Please use `const` to assign meaningful names to them...
144
145
  <DrawTool
145
146
  v-if="viewingMode === 'Annotation' && userInformation && !disableUI"
146
147
  :helpMode="helpMode"
148
+ :hoverVisibilities=hoverVisibilities
147
149
  :flatmapCanvas="this.$el"
148
- :inDrawing="inDrawing"
149
- :activeDrawTool="activeDrawTool"
150
150
  :drawnType="drawnType"
151
- :drawnTypes="drawnTypes"
151
+ :activeDrawTool="activeDrawTool"
152
152
  :activeDrawMode="activeDrawMode"
153
- :drawModes="drawModes"
154
- :connectionDisplay="connectionDisplay"
153
+ :drawnCreatedEvent="drawnCreatedEvent"
155
154
  :connectionEntry="connectionEntry"
156
155
  @drawToolbarEvent="drawToolbarEvent"
157
- @dialogDisplay="connectionDialogDisplay"
158
156
  @confirmDrawn="confirmDrawnFeature"
159
157
  @cancelDrawn="cancelDrawnFeature"
160
- @showFeatureTooltip="showConnectedFeatureTooltip"
161
- @hideFeatureTooltip="hideConnectedFeatureTooltip"
162
- @connection="(display) => connectionDisplay = display"
158
+ @featureTooltip="connectedFeatureTooltip"
159
+ @showTooltip="showTooltip"
160
+ @hideTooltip="hideTooltip"
161
+ ref="drawToolPopover"
163
162
  />
164
163
 
165
164
  <div class="bottom-right-control" v-show="!disableUI">
@@ -171,14 +170,15 @@ Please use `const` to assign meaningful names to them...
171
170
  width="70"
172
171
  popper-class="flatmap-popper"
173
172
  :visible="hoverVisibilities[0].value"
173
+ ref="zoomInPopover"
174
174
  >
175
175
  <template #reference>
176
176
  <map-svg-icon
177
177
  icon="zoomIn"
178
178
  class="icon-button zoomIn"
179
179
  @click="zoomIn()"
180
- @mouseover="showToolitip(0)"
181
- @mouseout="hideToolitip(0)"
180
+ @mouseover="showTooltip(0)"
181
+ @mouseout="hideTooltip(0)"
182
182
  />
183
183
  </template>
184
184
  </el-popover>
@@ -190,14 +190,15 @@ Please use `const` to assign meaningful names to them...
190
190
  width="70"
191
191
  popper-class="flatmap-popper"
192
192
  :visible="hoverVisibilities[1].value"
193
+ ref="zoomOutPopover"
193
194
  >
194
195
  <template #reference>
195
196
  <map-svg-icon
196
197
  icon="zoomOut"
197
198
  class="icon-button zoomOut"
198
199
  @click="zoomOut()"
199
- @mouseover="showToolitip(1)"
200
- @mouseout="hideToolitip(1)"
200
+ @mouseover="showTooltip(1)"
201
+ @mouseout="hideTooltip(1)"
201
202
  />
202
203
  </template>
203
204
  </el-popover>
@@ -209,6 +210,7 @@ Please use `const` to assign meaningful names to them...
209
210
  width="70"
210
211
  popper-class="flatmap-popper"
211
212
  :visible="hoverVisibilities[2].value"
213
+ ref="zoomFitPopover"
212
214
  >
213
215
  <div>
214
216
  Fit to
@@ -220,8 +222,8 @@ Please use `const` to assign meaningful names to them...
220
222
  icon="fitWindow"
221
223
  class="icon-button fitWindow"
222
224
  @click="resetView()"
223
- @mouseover="showToolitip(2)"
224
- @mouseout="hideToolitip(2)"
225
+ @mouseover="showTooltip(2)"
226
+ @mouseout="hideTooltip(2)"
225
227
  />
226
228
  </template>
227
229
  </el-popover>
@@ -249,6 +251,7 @@ Please use `const` to assign meaningful names to them...
249
251
  v-popover:checkBoxPopover
250
252
  >
251
253
  <svg-legends v-if="!isFC" class="svg-legends-container" />
254
+ <template v-if="showStarInLegend">
252
255
  <el-popover
253
256
  content="Location of the featured dataset"
254
257
  placement="right"
@@ -257,20 +260,20 @@ Please use `const` to assign meaningful names to them...
257
260
  width="max-content"
258
261
  :offset="-10"
259
262
  popper-class="flatmap-popper flatmap-teleport-popper"
260
- :visible="hoverVisibilities[9].value && showStarInLegend"
263
+ :visible="hoverVisibilities[9].value"
261
264
  ref="featuredMarkerPopover"
262
265
  >
263
266
  <template #reference>
264
267
  <div
265
- v-show="showStarInLegend"
266
268
  v-popover:featuredMarkerPopover
267
269
  class="yellow-star-legend"
268
270
  v-html="yellowstar"
269
- @mouseover="showToolitip(9)"
270
- @mouseout="hideToolitip(9)"
271
+ @mouseover="showTooltip(9)"
272
+ @mouseout="hideTooltip(9)"
271
273
  ></div>
272
274
  </template>
273
275
  </el-popover>
276
+ </template>
274
277
  <!-- The line below places the yellowstar svg on the left, and the text "Featured markers on the right" with css so they are both centered in the div -->
275
278
  <el-popover
276
279
  content="Find these markers for data"
@@ -310,6 +313,7 @@ Please use `const` to assign meaningful names to them...
310
313
  @changed="alertSelected"
311
314
  @checkboxMouseEnter="alertMouseEnterEmitted"
312
315
  @selections-data-changed="onSelectionsDataChanged"
316
+ @checkAll="checkAllAlerts"
313
317
  ref="alertSelection"
314
318
  key="alertSelection"
315
319
  />
@@ -357,6 +361,7 @@ Please use `const` to assign meaningful names to them...
357
361
  title="Studied in"
358
362
  labelKey="label"
359
363
  identifierKey="taxon"
364
+ helpMessage="Evidence exists that this set of neuron populations have been studied in the given species."
360
365
  :selections="taxonConnectivity"
361
366
  @changed="taxonsSelected"
362
367
  @checkboxMouseEnter="taxonMouseEnterEmitted"
@@ -554,6 +559,7 @@ Please use `const` to assign meaningful names to them...
554
559
  placement="right"
555
560
  :teleported="false"
556
561
  popper-class="flatmap-popper"
562
+ ref="openMapPopover"
557
563
  >
558
564
  <template #reference>
559
565
  <map-svg-icon
@@ -561,8 +567,8 @@ Please use `const` to assign meaningful names to them...
561
567
  ref="openMapRef"
562
568
  icon="openMap"
563
569
  class="icon-button open-map-button"
564
- @mouseover="showToolitip(8)"
565
- @mouseout="hideToolitip(8)"
570
+ @mouseover="showTooltip(8)"
571
+ @mouseout="hideTooltip(8)"
566
572
  />
567
573
  </template>
568
574
  </el-popover>
@@ -575,14 +581,15 @@ Please use `const` to assign meaningful names to them...
575
581
  :teleported="false"
576
582
  trigger="manual"
577
583
  popper-class="flatmap-popper"
584
+ ref="settingsPopover"
578
585
  >
579
586
  <template #reference>
580
587
  <map-svg-icon
581
588
  ref="backgroundIconRef"
582
589
  icon="changeBckgd"
583
590
  class="icon-button"
584
- @mouseover="showToolitip(3)"
585
- @mouseout="hideToolitip(3)"
591
+ @mouseover="showTooltip(3)"
592
+ @mouseout="hideTooltip(3)"
586
593
  />
587
594
  </template>
588
595
  </el-popover>
@@ -763,9 +770,9 @@ export default {
763
770
  * Function to initialise drawing.
764
771
  */
765
772
  initialiseDrawing: function () {
766
- this.inDrawing = false
767
- this.initialiseDialog()
773
+ this.connectionEntry = {}
768
774
  this.activeDrawTool = undefined
775
+ this.activeDrawMode = undefined
769
776
  this.drawnCreatedEvent = undefined
770
777
  },
771
778
  /**
@@ -785,19 +792,21 @@ export default {
785
792
  },
786
793
  /**
787
794
  * @vuese
788
- * Function to show connected features' tooltip for drawn connectivity.
795
+ * Function to display connected features' tooltip for drawn connectivity.
789
796
  * @arg id
790
797
  */
791
- showConnectedFeatureTooltip: function (id) {
798
+ connectedFeatureTooltip: function (value) {
792
799
  if (this.mapImp) {
793
- if (id) {
794
- const numericId = Number(id)
800
+ if (value) {
801
+ const numericId = Number(value)
795
802
  let payload = { feature: {} }
796
803
  if (numericId) {
797
804
  const data = this.mapImp.featureProperties(numericId)
798
805
  payload.feature = data
799
806
  } else {
800
- const drawnFeature = this.allDrawnFeatures.filter((feature) => feature.id === id.replace(' ', ''))[0]
807
+ const drawnFeature = this.existDrawnFeatures.find(
808
+ (feature) => feature.id === value.replace(' ', '')
809
+ )
801
810
  payload.feature.feature = drawnFeature
802
811
  }
803
812
  this.checkAndCreatePopups(payload)
@@ -806,17 +815,6 @@ export default {
806
815
  }
807
816
  }
808
817
  },
809
- /**
810
- * @vuese
811
- * Function to hide connected features' tooltip for drawn connectivity.
812
- * @arg id
813
- */
814
- hideConnectedFeatureTooltip: function (id) {
815
- if (this.mapImp) {
816
- // const numericId = Number(id)
817
- this.closeTooltip()
818
- }
819
- },
820
818
  /**
821
819
  * @vuese
822
820
  * Function to confirm a newly drawn feature.
@@ -833,26 +831,6 @@ export default {
833
831
  this.initialiseDrawing()
834
832
  }
835
833
  },
836
- /**
837
- * @vuese
838
- * Function to initialise connection dialog.
839
- */
840
- initialiseDialog: function () {
841
- this.connectionDisplay = false
842
- this.connectionEntry = {}
843
- },
844
- /**
845
- * @vuese
846
- * Function to display the connection dialog after finalising a drawing.
847
- */
848
- connectionDialogDisplay: function () {
849
- const inactive = this.$el.querySelector('.drawConnection').classList.contains('inactive')
850
- // disable click popup if icon inactive or in drawing
851
- if (!inactive && !this.inDrawing) {
852
- this.closeTooltip()
853
- this.connectionDisplay = !this.connectionDisplay
854
- }
855
- },
856
834
  /**
857
835
  * @vuese
858
836
  * Function to process the annotation toolbar click events.
@@ -860,29 +838,58 @@ export default {
860
838
  */
861
839
  drawToolbarEvent: function (type) {
862
840
  this.closeTooltip()
863
- if (this.drawnTypes.includes(type) && !this.activeDrawMode && !this.connectionDisplay) {
841
+ this.doubleClickedFeature = false
842
+ if (type === 'Delete') {
843
+ this.activeDrawMode = this.activeDrawMode === 'Delete' ? undefined : 'Delete'
844
+ } else if (type === 'Edit') {
845
+ this.activeDrawMode = this.activeDrawMode === 'Edit' ? undefined : 'Edit'
846
+ } else {
864
847
  this.activeDrawTool = type
865
- } else if (this.drawModes.includes(type) && !this.activeDrawTool) {
866
- if (type === 'Delete') {
867
- if (
868
- this.selectedDrawnFeature &&
869
- // For either no mode is on or edit is on
870
- (!this.activeDrawMode || this.activeDrawMode === 'Edit')
871
- ) {
872
- // Force simple_select a feature for delete event
873
- this.doubleClickedFeature = false
848
+ }
849
+ if (Object.keys(this.annotationEntry).length > 0 && !this.featureAnnotationSubmitted) {
850
+ this.rollbackAnnotationEvent()
851
+ }
852
+ },
853
+ /**
854
+ * @vuese
855
+ * Function to fire annotation event based on the provided ``data``.
856
+ * Either edit or delete event.
857
+ * @arg data
858
+ */
859
+ drawModeEvent: function (data) {
860
+ if (this.activeDrawMode === 'Edit') {
861
+ if (this.doubleClickedFeature) {
862
+ if (data.feature.feature.geometry.type !== 'Point') {
874
863
  this.changeAnnotationDrawMode({
875
- mode: 'simple_select',
876
- options: { featureIds: [this.selectedDrawnFeature.id] }
864
+ mode: 'direct_select',
865
+ options: { featureId: data.feature.feature.id }
877
866
  })
878
867
  this.modifyAnnotationFeature()
879
868
  }
880
- this.activeDrawMode = this.activeDrawMode === 'Delete' ? undefined : 'Delete'
881
- // clear selectedDrawnFeature when quit delete mode
882
- if (!this.activeDrawMode) this.selectedDrawnFeature = undefined
883
- } else if (type === 'Edit') {
884
- this.activeDrawMode = this.activeDrawMode === 'Edit' ? undefined : 'Edit'
869
+ this.doubleClickedFeature = false
870
+ }
871
+ }
872
+ if (this.activeDrawMode === 'Delete') {
873
+ this.changeAnnotationDrawMode({
874
+ mode: 'simple_select',
875
+ options: { featureIds: [data.feature.feature.id] }
876
+ })
877
+ this.modifyAnnotationFeature()
878
+ }
879
+ },
880
+ /**
881
+ * Function to create connectivity body from existing entries.
882
+ */
883
+ createConnectivityBody: function () {
884
+ if (Object.keys(this.connectionEntry).length > 0) {
885
+ const features = Object.values(this.connectionEntry)
886
+ const body = {
887
+ type: 'connectivity',
888
+ source: features[0],
889
+ target: features[features.length - 1],
890
+ intermediates: features.filter((f, index) => index !== 0 && index !== features.length - 1),
885
891
  }
892
+ this.annotationEntry.body = body
886
893
  }
887
894
  },
888
895
  /**
@@ -902,8 +909,7 @@ export default {
902
909
  clearAnnotationFeature: function () {
903
910
  if (
904
911
  this.mapImp &&
905
- this.allDrawnFeatures &&
906
- this.allDrawnFeatures.length > 0
912
+ this.existDrawnFeatures.length > 0
907
913
  ) {
908
914
  this.mapImp.clearAnnotationFeature()
909
915
  }
@@ -929,9 +935,10 @@ export default {
929
935
  // For 'updated' and 'deleted' callback
930
936
  if (
931
937
  this.mapImp &&
932
- this.drawnAnnotationEvent.includes(this.annotationEntry.type)
938
+ ['created', 'updated', 'deleted'].includes(this.annotationEntry.type)
933
939
  ) {
934
940
  this.mapImp.rollbackAnnotationEvent(this.annotationEntry)
941
+ this.annotationEntry = {}
935
942
  }
936
943
  },
937
944
  /**
@@ -942,14 +949,14 @@ export default {
942
949
  commitAnnotationEvent: function (annotation) {
943
950
  if (
944
951
  this.mapImp &&
945
- this.drawnAnnotationEvent.includes(this.annotationEntry.type) &&
952
+ ['created', 'updated', 'deleted'].includes(this.annotationEntry.type) &&
946
953
  // Only when annotation comments stored successfully
947
954
  annotation
948
955
  ) {
949
956
  this.featureAnnotationSubmitted = true
950
957
  this.mapImp.commitAnnotationEvent(this.annotationEntry)
951
958
  if (this.annotationEntry.type === 'deleted') this.closeTooltip()
952
- else this.addAnnotationFeature() // Update 'allDrawnFeatures' when created or updated event
959
+ else this.addAnnotationFeature() // Update 'existDrawnFeatures' when created or updated event
953
960
  }
954
961
  },
955
962
  /**
@@ -1005,11 +1012,13 @@ export default {
1005
1012
  if (this.drawnType !== 'None') {
1006
1013
  if (!this.featureAnnotationSubmitted) this.loading = true
1007
1014
  const userId = this.annotatedType === 'Anyone' ?
1008
- undefined : this.userInformation.orcid ? this.userInformation.orcid : '0000-0000-0000-0000'
1015
+ undefined : this.userInformation.orcid ?
1016
+ this.userInformation.orcid : '0000-0000-0000-0000'
1009
1017
  const participated = this.annotatedType === 'Anyone' ?
1010
- undefined : this.annotatedType === 'Me' ? true : false
1018
+ undefined : this.annotatedType === 'Me' ?
1019
+ true : false
1011
1020
  const drawnFeatures = await this.fetchDrawnFeatures(userId, participated)
1012
- this.allDrawnFeatures = drawnFeatures
1021
+ this.existDrawnFeatures = drawnFeatures
1013
1022
  this.loading = false
1014
1023
  if (!this.featureAnnotationSubmitted) {
1015
1024
  for (const feature of drawnFeatures) {
@@ -1041,6 +1050,7 @@ export default {
1041
1050
  this.drawnType = flag
1042
1051
  if (this.mapImp) {
1043
1052
  this.addAnnotationFeature()
1053
+ this.initialiseDrawing()
1044
1054
  }
1045
1055
  },
1046
1056
  /**
@@ -1270,9 +1280,6 @@ export default {
1270
1280
  // Check and flatten the origins node graph
1271
1281
  let originsFlat = connectivity?.ids?.dendrites?.flat().flat()
1272
1282
 
1273
- // Remove the origin nodes from the path features so that we only see downstream nodes
1274
- pathFeatures = pathFeatures.filter((p) => !originsFlat.includes(p.models))
1275
-
1276
1283
  let toHighlight = []
1277
1284
  let highlight = false
1278
1285
 
@@ -1302,6 +1309,32 @@ export default {
1302
1309
  this.mapImp.zoomToFeatures(toHighlight, { noZoomIn: true })
1303
1310
  }
1304
1311
  },
1312
+ resetMapFilter: function() {
1313
+ const alert = this.mapFilters.alert;
1314
+ let filter = undefined;
1315
+ if (alert.with) {
1316
+ if (!alert.without) {
1317
+ filter = {
1318
+ HAS: 'alert',
1319
+ };
1320
+ }
1321
+ } else {
1322
+ if (alert.without) {
1323
+ filter = {
1324
+ NOT: { HAS: 'alert'},
1325
+ };
1326
+ } else {
1327
+ filter = {
1328
+ AND: [ {NOT: { HAS: 'alert'}}, { HAS: 'alert'}]
1329
+ }
1330
+ }
1331
+ }
1332
+ if (filter) {
1333
+ this.mapImp.setVisibilityFilter(filter)
1334
+ } else {
1335
+ this.mapImp.clearVisibilityFilter()
1336
+ }
1337
+ },
1305
1338
  /**
1306
1339
  * @vuese
1307
1340
  * Function to enable/disable mouse enter and leave event for
@@ -1311,15 +1344,19 @@ export default {
1311
1344
  alertMouseEnterEmitted: function (payload) {
1312
1345
  if (this.mapImp) {
1313
1346
  if (payload.value) {
1314
- const ALERT_FILTER = {
1315
- HAS: 'alert',
1347
+ let filter = undefined;
1348
+ if (payload.key === "alert") {
1349
+ filter = {
1350
+ HAS: 'alert',
1351
+ }
1352
+ } else if (payload.key === "withoutAlert") {
1353
+ filter = {
1354
+ NOT: {HAS: 'alert'},
1355
+ }
1316
1356
  }
1317
- this.mapImp.setVisibilityFilter(ALERT_FILTER)
1357
+ this.mapImp.setVisibilityFilter(filter)
1318
1358
  } else {
1319
- this.mapImp.clearVisibilityFilter()
1320
- this.alertSelected({
1321
- value: (payload.checked.length > 0),
1322
- });
1359
+ this.resetMapFilter()
1323
1360
  }
1324
1361
  }
1325
1362
  },
@@ -1330,15 +1367,39 @@ export default {
1330
1367
  * @arg payload
1331
1368
  */
1332
1369
  alertSelected: function (payload) {
1370
+ if (this.mapImp) {
1371
+ if (payload.key === "alert") {
1372
+ if (payload.value) {
1373
+ this.mapFilters.alert.with = true
1374
+ } else {
1375
+ this.mapFilters.alert.with = false
1376
+ }
1377
+ } else if (payload.key === "withoutAlert") {
1378
+ if (payload.value) {
1379
+ this.mapFilters.alert.without = true
1380
+ } else {
1381
+ this.mapFilters.alert.without = false
1382
+ }
1383
+ }
1384
+ this.resetMapFilter()
1385
+ }
1386
+ },
1387
+ /**
1388
+ * @vuese
1389
+ * Function to enable/disable (show/hide) all alerts
1390
+ * option by providing ``flag`` (true/false).
1391
+ * @arg flag
1392
+ */
1393
+ checkAllAlerts: function (payload) {
1333
1394
  if (this.mapImp) {
1334
1395
  if (payload.value) {
1335
- this.mapImp.clearVisibilityFilter()
1396
+ this.mapFilters.alert.without = true
1397
+ this.mapFilters.alert.with = true
1336
1398
  } else {
1337
- const ALERT_FILTER = {
1338
- NOT: {HAS: 'alert'}
1339
- }
1340
- this.mapImp.setVisibilityFilter(ALERT_FILTER)
1399
+ this.mapFilters.alert.without = false
1400
+ this.mapFilters.alert.with = false
1341
1401
  }
1402
+ this.resetMapFilter()
1342
1403
  }
1343
1404
  },
1344
1405
  /**
@@ -1483,28 +1544,25 @@ export default {
1483
1544
  if (!this.featureAnnotationSubmitted) this.rollbackAnnotationEvent()
1484
1545
  else this.featureAnnotationSubmitted = false
1485
1546
  } else if (data.type === 'modeChanged') {
1486
- // 'modeChanged' event is before 'created' event
1487
- if (data.feature.mode.startsWith('draw_')) {
1488
- // Reset data entry for every draw
1489
- this.initialiseDialog()
1490
- this.inDrawing = true
1491
- } else if (data.feature.mode === 'simple_select' && this.inDrawing) {
1492
- if (this.drawnCreatedEvent) this.connectionDisplay = true
1493
- else this.initialiseDrawing() // Reset if invalid linestring or polygon
1547
+ if (data.feature.mode === 'simple_select' && this.activeDrawTool) {
1548
+ if (!this.drawnCreatedEvent) this.initialiseDrawing() // Reset if invalid linestring or polygon
1494
1549
  } else if (data.feature.mode === 'direct_select') {
1495
1550
  this.doubleClickedFeature = true
1496
1551
  }
1497
1552
  } else if (data.type === 'selectionChanged') {
1498
- this.selectedDrawnFeature =
1499
- data.feature.features.length === 0 ? undefined : data.feature.features[0]
1553
+ this.selectedDrawnFeature = data.feature.features.length === 0 ?
1554
+ undefined : data.feature.features[0]
1500
1555
  payload.feature.feature = this.selectedDrawnFeature
1501
- if (!this.inDrawing) { // Make sure dialog content doesn't change
1502
- this.initialiseDialog()
1556
+ if (!this.activeDrawTool) { // Make sure dialog content doesn't change
1557
+ this.connectionEntry = {}
1503
1558
  // For exist drawn annotation features
1504
1559
  if (this.selectedDrawnFeature) {
1505
- let feature = this.allDrawnFeatures
1506
- .filter((feature) => feature.id === this.selectedDrawnFeature.id)[0]
1507
- if (feature && feature.connection) this.connectionEntry = feature.connection
1560
+ const drawnFeature = this.existDrawnFeatures.find(
1561
+ (feature) => feature.id === this.selectedDrawnFeature.id
1562
+ )
1563
+ if (drawnFeature && drawnFeature.connection) {
1564
+ this.connectionEntry = drawnFeature.connection
1565
+ }
1508
1566
  this.drawModeEvent(payload)
1509
1567
  }
1510
1568
  }
@@ -1541,7 +1599,6 @@ export default {
1541
1599
  this.annotationEventCallback(payload, data)
1542
1600
  } else {
1543
1601
  if (eventType !== 'pan-zoom') {
1544
- this.featuresAlert = data.alert
1545
1602
  const label = data.label
1546
1603
  const resource = [data.models]
1547
1604
  const taxonomy = this.entry
@@ -1567,20 +1624,22 @@ export default {
1567
1624
  provenanceTaxonomy: taxons,
1568
1625
  }
1569
1626
  if (eventType === 'click') {
1627
+ this.featuresAlert = data.alert
1570
1628
  if (this.viewingMode === 'Network Discovery') {
1571
1629
  this.highlightConnectedPaths([data.models])
1572
1630
  } else {
1573
1631
  this.currentActive = data.models ? data.models : ''
1574
- // Stop adding features if dialog displayed
1575
- if (this.inDrawing && !this.connectionDisplay) {
1576
- // Only clicked connection data will be added
1577
- let nodeLabel = data.label ? data.label : `Feature ${data.id}`
1578
- const validDrawnFeature = data.featureId ||
1579
- this.allDrawnFeatures.find((feature) => feature.id === data.id)
1580
- // only the linestring will have connection at the current stage
1632
+ // Drawing connectivity between features
1633
+ if (this.activeDrawTool && !this.drawnCreatedEvent) {
1634
+ // Check if flatmap features or existing drawn features
1635
+ const validDrawnFeature = data.featureId || this.existDrawnFeatures.find(
1636
+ (feature) => feature.id === data.id
1637
+ )
1638
+ // Only the linestring will have connection
1581
1639
  if (this.activeDrawTool === 'LineString' && validDrawnFeature) {
1582
1640
  const key = data.featureId ? data.featureId : data.id
1583
- // add space before key to make sure properties follows adding order
1641
+ const nodeLabel = data.label ? data.label : `Feature ${data.id}`
1642
+ // Add space before key to make sure properties follows adding order
1584
1643
  this.connectionEntry[` ${key}`] = Object.assign({ label: nodeLabel },
1585
1644
  Object.fromEntries(
1586
1645
  Object.entries(data)
@@ -1601,7 +1660,7 @@ export default {
1601
1660
  eventType === 'click' &&
1602
1661
  !(this.viewingMode === 'Network Discovery') &&
1603
1662
  // Disable popup when drawing
1604
- !this.inDrawing
1663
+ !this.activeDrawTool
1605
1664
  ) {
1606
1665
  this.checkAndCreatePopups(payload)
1607
1666
  }
@@ -1612,50 +1671,6 @@ export default {
1612
1671
  }
1613
1672
  }
1614
1673
  },
1615
- /**
1616
- * @vuese
1617
- * Function to fire annotation event based on the provided ``data``.
1618
- * Either edit or delete event.
1619
- * @arg data
1620
- */
1621
- drawModeEvent: function (data) {
1622
- if (this.activeDrawMode) {
1623
- if (this.doubleClickedFeature) { // double click fires 'updated' callback
1624
- if (data.feature.feature.geometry.type !== 'Point') {
1625
- // show tooltip and enter edit mode
1626
- this.changeAnnotationDrawMode({
1627
- mode: 'direct_select',
1628
- options: { featureId: data.feature.feature.id }
1629
- })
1630
- this.modifyAnnotationFeature()
1631
- }
1632
- this.doubleClickedFeature = false
1633
- } else { // single click fires delete
1634
- if (this.activeDrawMode === 'Delete') {
1635
- this.changeAnnotationDrawMode({
1636
- mode: 'simple_select',
1637
- options: { featureIds: [data.feature.feature.id] }
1638
- })
1639
- this.modifyAnnotationFeature()
1640
- }
1641
- }
1642
- }
1643
- },
1644
- /**
1645
- * Function to create connectivity body from existing entries.
1646
- */
1647
- createConnectivityBody: function () {
1648
- if (Object.keys(this.connectionEntry).length > 0) {
1649
- const features = Object.values(this.connectionEntry)
1650
- const body = {
1651
- type: 'connectivity',
1652
- source: features[0],
1653
- target: features[features.length - 1],
1654
- intermediates: features.slice(1, -1),
1655
- }
1656
- this.annotationEntry.body = body
1657
- }
1658
- },
1659
1674
  /**
1660
1675
  * @vuese
1661
1676
  * Function triggered by viewing mode change.
@@ -1683,21 +1698,21 @@ export default {
1683
1698
  if (data.feature.featureId && data.feature.models) {
1684
1699
  this.displayTooltip(data.feature.models)
1685
1700
  } else if (data.feature.feature) {
1686
- if (this.inDrawing || this.activeDrawMode || this.connectionDisplay) {
1701
+ // in drawing or edit/delete mode is on or has connectivity
1702
+ if (
1703
+ this.activeDrawTool ||
1704
+ this.activeDrawMode ||
1705
+ Object.keys(this.connectionEntry).length > 0
1706
+ ) {
1687
1707
  this.featureAnnotationSubmitted = false
1688
1708
  this.annotationEntry.featureId = data.feature.feature.id
1689
- if (this.inDrawing) this.createConnectivityBody()
1709
+ if (this.activeDrawTool) this.createConnectivityBody()
1690
1710
  this.displayTooltip(
1691
1711
  data.feature.feature.id,
1692
1712
  centroid(data.feature.feature.geometry)
1693
1713
  )
1694
- // Hide dialog when updated or deleted event is fired and tooltip is displayed
1695
- if (this.activeDrawMode) this.initialiseDialog()
1696
1714
  } else {
1697
- // Not allowed to update feature if not on edit mode
1698
- if (data.feature.type === 'updated') {
1699
- this.rollbackAnnotationEvent()
1700
- }
1715
+ this.rollbackAnnotationEvent()
1701
1716
  }
1702
1717
  }
1703
1718
  } else {
@@ -1825,17 +1840,76 @@ export default {
1825
1840
  * @arg helpMode
1826
1841
  */
1827
1842
  setHelpMode: function (helpMode) {
1828
- if (helpMode) {
1829
- // because some tooltips are inside drawer
1830
- this.drawerOpen = true;
1831
- // wait for CSS transition
1832
- setTimeout(() => {
1833
- this.inHelp = true;
1834
- this.hoverVisibilities.forEach((item) => {
1835
- item.value = true;
1836
- });
1843
+ const toolTipsLength = this.hoverVisibilities.length;
1844
+ const lastIndex = toolTipsLength - 1;
1845
+ const activePopoverObj = this.hoverVisibilities[this.helpModeActiveIndex];
1846
+
1847
+ if (activePopoverObj) {
1848
+ const popoverRefsId = activePopoverObj?.refs;
1849
+ const popoverRefId = activePopoverObj?.ref;
1850
+ const popoverRef = this.$refs[popoverRefsId ? popoverRefsId : popoverRefId];
1851
+
1852
+ if (popoverRef) {
1853
+ // Open pathway drawer if the tooltip is inside or beside
1854
+ const { parentElement, nextElementSibling } = popoverRef.$el;
1855
+ const isPathwayContainer = (element) => {
1856
+ return element && (
1857
+ element.classList.contains('pathway-container') ||
1858
+ element.classList.contains('pathway-location')
1859
+ );
1860
+ };
1861
+
1862
+ if (
1863
+ isPathwayContainer(parentElement) ||
1864
+ isPathwayContainer(nextElementSibling)
1865
+ ) {
1866
+ this.drawerOpen = true;
1867
+ }
1868
+ } else {
1869
+ // skip the unavailable tooltips
1870
+ this.helpModeActiveIndex += 1;
1871
+ }
1872
+ }
1873
+
1874
+ if (!helpMode) {
1875
+ // reset to iniital state
1876
+ this.helpModeActiveIndex = this.helpModeInitialIndex;
1877
+ }
1878
+
1879
+ if (this.viewingMode !== 'Annotation' && this.helpModeActiveIndex > 9) {
1880
+ this.helpModeActiveIndex = lastIndex
1881
+ }
1882
+
1883
+ if (helpMode && this.helpModeActiveIndex >= lastIndex) {
1884
+ /**
1885
+ * This event is emitted when the tooltips in help mode reach the last item.
1886
+ */
1887
+ this.$emit('help-mode-last-item', true);
1888
+ }
1889
+
1890
+ if (helpMode && !this.helpModeDialog) {
1891
+ this.inHelp = true;
1892
+ this.hoverVisibilities.forEach((item) => {
1893
+ item.value = true;
1894
+ });
1895
+ } else if (helpMode && this.helpModeDialog && toolTipsLength > this.helpModeActiveIndex) {
1896
+
1897
+ // Show the map tooltip as first item
1898
+ if (this.helpModeActiveIndex > -1) {
1899
+ this.closeFlatmapHelpPopup();
1900
+
1901
+ // wait for CSS transition
1902
+ setTimeout(() => {
1903
+ this.inHelp = false;
1904
+ this.hoverVisibilities.forEach((item) => {
1905
+ item.value = false;
1906
+ });
1907
+
1908
+ this.showTooltip(this.helpModeActiveIndex, 200);
1909
+ }, 300);
1910
+ } else if (this.helpModeActiveIndex === -1) {
1837
1911
  this.openFlatmapHelpPopup();
1838
- }, 300);
1912
+ }
1839
1913
  } else {
1840
1914
  this.inHelp = false
1841
1915
  this.hoverVisibilities.forEach((item) => {
@@ -1850,12 +1924,16 @@ export default {
1850
1924
  * by providing ``tooltipNumber``.
1851
1925
  * @arg tooltipNumber
1852
1926
  */
1853
- showToolitip: function (tooltipNumber) {
1927
+ showTooltip: function (tooltipNumber, timeout = 500) {
1854
1928
  if (!this.inHelp) {
1855
1929
  clearTimeout(this.tooltipWait[tooltipNumber])
1856
1930
  this.tooltipWait[tooltipNumber] = setTimeout(() => {
1857
1931
  this.hoverVisibilities[tooltipNumber].value = true
1858
- }, 500)
1932
+ /**
1933
+ * This event is emitted after a tooltip in Flatmap is shown.
1934
+ */
1935
+ this.$emit('shown-tooltip');
1936
+ }, timeout)
1859
1937
  }
1860
1938
  },
1861
1939
  /**
@@ -1864,12 +1942,12 @@ export default {
1864
1942
  * by providing ``tooltipNumber``.
1865
1943
  * @arg tooltipNumber
1866
1944
  */
1867
- hideToolitip: function (tooltipNumber) {
1945
+ hideTooltip: function (tooltipNumber, timeout = 500) {
1868
1946
  if (!this.inHelp) {
1869
1947
  clearTimeout(this.tooltipWait[tooltipNumber])
1870
1948
  this.tooltipWait[tooltipNumber] = setTimeout(() => {
1871
1949
  this.hoverVisibilities[tooltipNumber].value = false
1872
- }, 500)
1950
+ }, timeout)
1873
1951
  }
1874
1952
  },
1875
1953
  /**
@@ -1887,7 +1965,7 @@ export default {
1887
1965
  options.annotationFeatureGeometry = geometry
1888
1966
  } else {
1889
1967
  featureId = this.mapImp.modelFeatureIds(feature)[0]
1890
- if (!this.inDrawing) {
1968
+ if (!this.activeDrawTool) {
1891
1969
  options.positionAtLastClick = true
1892
1970
  }
1893
1971
  }
@@ -1911,6 +1989,10 @@ export default {
1911
1989
  anchor: 'top',
1912
1990
  className: 'flatmap-popup-popper',
1913
1991
  })
1992
+ /**
1993
+ * This event is emitted after a tooltip on Flatmap's map is shown.
1994
+ */
1995
+ this.$emit('shown-map-tooltip');
1914
1996
  }
1915
1997
  }
1916
1998
  },
@@ -2275,6 +2357,37 @@ export default {
2275
2357
  type: Boolean,
2276
2358
  default: false,
2277
2359
  },
2360
+ /**
2361
+ * The active item index of help mode.
2362
+ */
2363
+ helpModeActiveItem: {
2364
+ type: Number,
2365
+ default: 0,
2366
+ },
2367
+ /**
2368
+ * The option to use helpModeDialog.
2369
+ * On default, `false`, clicking help will show all tooltips.
2370
+ * If `true`, clicking help will show the help-mode-dialog.
2371
+ */
2372
+ helpModeDialog: {
2373
+ type: Boolean,
2374
+ default: false,
2375
+ },
2376
+ /**
2377
+ * The last item of help mode.
2378
+ */
2379
+ helpModeLastItem: {
2380
+ type: Boolean,
2381
+ default: false,
2382
+ },
2383
+ /**
2384
+ * The initial index number for help mode tooltips.
2385
+ * Set negative (e.g. -2) if there are other tooltips outside of `hoverVisibilities`.
2386
+ */
2387
+ helpModeInitialIndex: {
2388
+ type: Number,
2389
+ default: 0,
2390
+ },
2278
2391
  /**
2279
2392
  * The option to create map on component mounted.
2280
2393
  */
@@ -2310,22 +2423,6 @@ export default {
2310
2423
  */
2311
2424
  openMapOptions: {
2312
2425
  type: Array,
2313
- /**
2314
- * ```[
2315
- {
2316
- display: 'Open AC Map',
2317
- key: 'AC',
2318
- },
2319
- {
2320
- display: 'Open FC Map',
2321
- key: 'FC',
2322
- },
2323
- {
2324
- display: 'Open 3D Human Map',
2325
- key: '3D',
2326
- },
2327
- ]```
2328
- */
2329
2426
  default: function () {
2330
2427
  return [
2331
2428
  {
@@ -2399,8 +2496,8 @@ export default {
2399
2496
  flatmapAPI: this.flatmapAPI,
2400
2497
  sparcAPI: this.sparcAPI,
2401
2498
  $annotator: this.annotator,
2402
- userApiKey: this.userToken,
2403
2499
  getFeaturesAlert: () => this.featuresAlert,
2500
+ userApiKey: this.userToken,
2404
2501
  }
2405
2502
  },
2406
2503
  data: function () {
@@ -2430,17 +2527,24 @@ export default {
2430
2527
  taxonConnectivity: [],
2431
2528
  pathwaysMaxHeight: 1000,
2432
2529
  hoverVisibilities: [
2433
- { value: false },
2434
- { value: false },
2435
- { value: false },
2436
- { value: false },
2437
- { value: false },
2438
- { value: false },
2439
- { value: false },
2440
- { value: false },
2441
- { value: false },
2442
- { value: false },
2530
+ { value: false, ref: 'zoomInPopover' }, // 0
2531
+ { value: false, ref: 'zoomOutPopover' }, // 1
2532
+ { value: false, ref: 'zoomFitPopover' }, // 2
2533
+ { value: false, ref: 'settingsPopover' }, // 3
2534
+ { value: false, ref: 'checkBoxPopover' }, // 4
2535
+ { value: false, ref: 'markerPopover' }, // 5
2536
+ { value: false, ref: 'warningPopover' }, // 6
2537
+ { value: false, ref: 'whatsNewPopover' }, // 7
2538
+ { value: false, ref: 'openMapPopover' }, // 8
2539
+ { value: false, ref: 'featuredMarkerPopover' }, // 9
2540
+ { value: false, refs: 'drawToolPopover', ref: 'connectionPopover' }, // 10
2541
+ { value: false, refs: 'drawToolPopover', ref: 'drawPointPopover' }, // 11
2542
+ { value: false, refs: 'drawToolPopover', ref: 'drawLinePopover' }, // 12
2543
+ { value: false, refs: 'drawToolPopover', ref: 'drawPolygonPopover' }, // 13
2544
+ { value: false, refs: 'drawToolPopover', ref: 'deletePopover' }, // 14
2545
+ { value: false, refs: 'drawToolPopover', ref: 'editPopover' }, // 15
2443
2546
  ],
2547
+ helpModeActiveIndex: this.helpModeInitialIndex,
2444
2548
  yellowstar: yellowstar,
2445
2549
  isFC: false,
2446
2550
  inHelp: false,
@@ -2472,13 +2576,10 @@ export default {
2472
2576
  annotator: undefined,
2473
2577
  userInformation: undefined,
2474
2578
  activeDrawTool: undefined,
2475
- drawnAnnotationEvent: ['created', 'updated', 'deleted'],
2476
2579
  drawnCreatedEvent: undefined,
2477
2580
  featureAnnotationSubmitted: false,
2478
- inDrawing: false,
2479
- connectionDisplay: false,
2480
2581
  connectionEntry: {},
2481
- allDrawnFeatures: undefined, // Store all exist drawn features
2582
+ existDrawnFeatures: [], // Store all exist drawn features
2482
2583
  doubleClickedFeature: false,
2483
2584
  activeDrawMode: undefined,
2484
2585
  drawModes: ['Delete', 'Edit'],
@@ -2489,14 +2590,22 @@ export default {
2489
2590
  key: 'alert',
2490
2591
  enabled: true,
2491
2592
  },
2593
+ {
2594
+ label: 'Display Path Without Alerts',
2595
+ key: 'withoutAlert',
2596
+ enabled: true,
2597
+ },
2492
2598
  ],
2599
+ mapFilters: markRaw({
2600
+ alert: {
2601
+ with: true,
2602
+ without: true,
2603
+ }
2604
+ })
2493
2605
  }
2494
2606
  },
2495
2607
  computed: {
2496
- ...mapState(useMainStore, ['userToken']),
2497
- connection: function () {
2498
- return Object.keys(this.connectionEntry).length > 0
2499
- }
2608
+ ...mapState(useMainStore, ['userToken'])
2500
2609
  },
2501
2610
  watch: {
2502
2611
  entry: function () {
@@ -2507,6 +2616,14 @@ export default {
2507
2616
  this.setHelpMode(newVal)
2508
2617
  }
2509
2618
  },
2619
+ helpModeActiveItem: function () {
2620
+ // just take the action from helpModeActiveItem
2621
+ // work with local value since the indexing is different
2622
+ if (this.helpMode) {
2623
+ this.helpModeActiveIndex += 1;
2624
+ this.setHelpMode(this.helpMode);
2625
+ }
2626
+ },
2510
2627
  state: {
2511
2628
  handler: function (state, oldVal) {
2512
2629
  if (state !== oldVal) {
@@ -2529,7 +2646,7 @@ export default {
2529
2646
  this.showAnnotator(true)
2530
2647
  this.userInformation = userData
2531
2648
  this.setFeatureAnnotated()
2532
- if (!this.allDrawnFeatures) {
2649
+ if (this.existDrawnFeatures.length === 0) {
2533
2650
  this.addAnnotationFeature()
2534
2651
  }
2535
2652
  }
@@ -2537,6 +2654,11 @@ export default {
2537
2654
  })
2538
2655
  } else this.showAnnotator(false)
2539
2656
  },
2657
+ activeDrawMode: function () {
2658
+ // Deselect any feature when draw mode is changed
2659
+ this.changeAnnotationDrawMode({ mode: 'simple_select' })
2660
+ this.connectionEntry = {}
2661
+ },
2540
2662
  disableUI: function (isUIDisabled) {
2541
2663
  if (isUIDisabled) {
2542
2664
  this.closeTooltip()
@@ -3076,7 +3198,21 @@ export default {
3076
3198
 
3077
3199
  :deep(.flatmap-popup-popper) {
3078
3200
  .maplibregl-popup-tip {
3201
+ margin-bottom: -1px;
3079
3202
  border-bottom-color: $app-primary-color;
3203
+ position: relative;
3204
+
3205
+ &::before {
3206
+ content: "";
3207
+ display: block;
3208
+ width: 0;
3209
+ height: 0;
3210
+ border: 10px solid transparent;
3211
+ border-bottom-color: #f3ecf6;
3212
+ position: absolute;
3213
+ top: -9px;
3214
+ left: -10px;
3215
+ }
3080
3216
  }
3081
3217
  .maplibregl-popup-content {
3082
3218
  padding: 6px 4px;