@abi-software/mapintegratedvuer 1.6.5 → 1.7.1-beta.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abi-software/mapintegratedvuer",
3
- "version": "1.6.5",
3
+ "version": "1.7.1-beta.0",
4
4
  "license": "Apache-2.0",
5
5
  "scripts": {
6
6
  "serve": "vite --host --force",
@@ -50,12 +50,12 @@
50
50
  "*.js"
51
51
  ],
52
52
  "dependencies": {
53
- "@abi-software/flatmapvuer": "^1.6.2",
54
- "@abi-software/map-side-bar": "^2.5.2",
55
- "@abi-software/map-utilities": "^1.2.1",
53
+ "@abi-software/flatmapvuer": "1.7.2",
54
+ "@abi-software/map-side-bar": "2.6.2",
55
+ "@abi-software/map-utilities": "1.3.1",
56
56
  "@abi-software/plotvuer": "^1.0.3",
57
- "@abi-software/scaffoldvuer": "^1.6.2",
58
- "@abi-software/simulationvuer": "^1.0.1",
57
+ "@abi-software/scaffoldvuer": "1.7.1",
58
+ "@abi-software/simulationvuer": "1.0.1",
59
59
  "@abi-software/sparc-annotation": "0.3.2",
60
60
  "@abi-software/svg-sprite": "^1.0.1",
61
61
  "@element-plus/icons-vue": "^2.3.1",
@@ -81,6 +81,7 @@
81
81
  "concurrently": "^8.2.2",
82
82
  "cypress": "^13.13.0",
83
83
  "cypress-multi-reporters": "^1.6.4",
84
+ "cypress-visual-regression": "^5.2.2",
84
85
  "cypress-wait-until": "^1.7.1",
85
86
  "dom-parser": "^0.1.6",
86
87
  "eslint": "^8.56.0",
package/src/App.vue CHANGED
@@ -20,6 +20,7 @@
20
20
  <el-button @click="setMultiFlatmap()" size="small">Set MultiFlatmap</el-button>
21
21
  <el-button @click="setLegacyMultiFlatmap()" size="small">Set Legacy MultiFlatmap</el-button>
22
22
  <el-button @click="setScaffold()" size="small">Set To Scaffold</el-button>
23
+ <el-button @click="setWholebody()" size="small">Set to Wholebody</el-button>
23
24
  <el-button @click="setFlatmap()" size="small">Set Flatmap</el-button>
24
25
  <el-button @click="setSearch()" size="small">Set Search</el-button>
25
26
  </el-row>
@@ -166,6 +167,15 @@ export default {
166
167
  }
167
168
  );
168
169
  },
170
+ setWholebody: function() {
171
+ this.$refs.map.setCurrentEntry(
172
+ {
173
+ type: "Scaffold",
174
+ label: "Human",
175
+ isBodyScaffold: true
176
+ }
177
+ );
178
+ },
169
179
  setSearch: function() {
170
180
  this.$refs.map.openSearch([], "10.26275/1uno-tynt");
171
181
  },
@@ -13,7 +13,7 @@
13
13
  <el-option
14
14
  v-for="entry in entries"
15
15
  :key="entry.id"
16
- :label="getEntryTitle(entry)"
16
+ :label="getTitle(entry)"
17
17
  :value="entry.id"
18
18
  />
19
19
  </el-select>
@@ -126,6 +126,7 @@ export default {
126
126
  boundariesElement: null, // this is set @vue:mounted by the parent component via the 'setBoundary' method
127
127
  showDetails: true,
128
128
  contextCardEntry: undefined,
129
+ titles: [],
129
130
  }
130
131
  },
131
132
  computed: {
@@ -168,7 +169,18 @@ export default {
168
169
  }
169
170
  },
170
171
  entries: function() {
171
- return this.entriesStore.entries;
172
+ this.titles = [];
173
+ return this.entriesStore.entries.map((entry) => {
174
+ const title = this.getEntryTitle(entry);
175
+ this.titles.push({
176
+ id: entry.id,
177
+ title: title,
178
+ });
179
+ return {
180
+ ...entry,
181
+ title: title,
182
+ };
183
+ });
172
184
  },
173
185
  },
174
186
  methods: {
@@ -184,13 +196,43 @@ export default {
184
196
  type = "3D Scaffold";
185
197
  title += type;
186
198
  if (entry.datasetId)
187
- title += " (" + entry.datasetId + ")";
199
+ title += " - " + entry.datasetId + "";
188
200
  else if (entry.discoverId)
189
- title += " (" + entry.discoverId + ")";
201
+ title += " - " + entry.discoverId + "";
202
+
190
203
  return title;
191
204
  }
192
205
  return "Viewer";
193
206
  },
207
+ getTitle: function(_entry) {
208
+ const {id, title} = _entry;
209
+ const foundTitles = this.titles.filter((t) => t.title === title);
210
+
211
+ if (foundTitles.length > 1) {
212
+ const titleList = [];
213
+
214
+ for (let i = 0; i < foundTitles.length; i++) {
215
+ const alpha = this.getCharById(i);
216
+
217
+ titleList.push({
218
+ id: foundTitles[i].id,
219
+ title: foundTitles[i].title + alpha,
220
+ });
221
+ }
222
+
223
+ const titleToReturn = titleList.find(t => t.id === id);
224
+ if (titleToReturn) {
225
+ return titleToReturn.title;
226
+ }
227
+ }
228
+
229
+ return title;
230
+ },
231
+ getCharById: function(id) {
232
+ // starts from char 'A'
233
+ const character = ' (' + String.fromCharCode(65 + id) + ')';
234
+ return character;
235
+ },
194
236
  viewerChanged: function(value) {
195
237
  if (this.entry.id && this.entry.id != value) {
196
238
  this.splitFlowStore.assignOrSwapPaneWithIds({
@@ -261,32 +303,37 @@ export default {
261
303
  display:flex;
262
304
  flex-direction: row;
263
305
  .select-box {
264
- width: 177px;
265
- height: 26px;
266
- border-radius: 4px;
267
- border: 1px solid rgb(144, 147, 153);
268
- background-color: #fff;
269
- font-weight: 500;
270
- color: rgb(48, 49, 51);
271
- margin-left: 8px;
272
- margin-top: 3px;
273
- margin-bottom: 2px;
306
+ max-width: 300px;
274
307
  z-index: 5;
275
308
  :deep(.el-select__wrapper) {
276
- width:177px;
277
309
  color: $app-primary-color;
278
- height: 26px;
279
- min-height: 26px;
280
- line-height: 26px;
281
- padding-left: 4px;
310
+ height: 29px;
311
+ min-height: 29px;
312
+ line-height: 29px;
313
+ font-weight: 500;
314
+ margin-top: 1px;
315
+ margin-left: 8px;
316
+ padding-left: 8px;
282
317
  padding-right: 8px;
283
- background-color: #fff;
284
- border-style: none;
318
+ box-shadow: none !important;
319
+ background: transparent;
285
320
  span {
286
321
  color: $app-primary-color;
287
322
  }
288
323
  }
289
324
 
325
+ :deep(.el-select__placeholder) {
326
+ width: fit-content;
327
+ position: relative;
328
+ top: auto;
329
+ transform: none;
330
+ min-width: 80px;
331
+ }
332
+
333
+ :deep(.el-select__caret) {
334
+ color: $app-primary-color;
335
+ }
336
+
290
337
  :deep(.el-input__icon) {
291
338
  line-height: 24px;
292
339
  color: $lightGrey;
@@ -27,7 +27,7 @@ import { useSettingsStore } from '../stores/settings';
27
27
  import { useSplitFlowStore } from '../stores/splitFlow';
28
28
  import { findSpeciesKey } from './scripts/utilities.js';
29
29
  import { MapSvgSpriteColor} from '@abi-software/svg-sprite';
30
- import { initialState } from "./scripts/utilities.js";
30
+ import { initialState, getBodyScaffoldInfo } from "./scripts/utilities.js";
31
31
  import RetrieveContextCardMixin from "../mixins/RetrieveContextCardMixin.js"
32
32
  import {
33
33
  ElLoading as Loading
@@ -155,6 +155,9 @@ export default {
155
155
  } else if (document.msExitFullscreen) { /* IE/Edge */
156
156
  document.msExitFullscreen();
157
157
  }
158
+
159
+ let mapApp = this.$refs.MapApp;
160
+ this.replacePopupsOnFullscreen(mapApp, document.body);
158
161
  }
159
162
  },
160
163
  /**
@@ -172,6 +175,15 @@ export default {
172
175
  } else if (parent.msRequestFullscreen) { /* IE/Edge */
173
176
  mapApp.msRequestFullscreen();
174
177
  }
178
+
179
+ this.replacePopupsOnFullscreen(document.body, mapApp);
180
+ },
181
+ replacePopupsOnFullscreen: function (containerA, containerB) {
182
+ const allTeleportedPopovers = containerA.querySelectorAll('[id^="el-popper-container"]');
183
+
184
+ allTeleportedPopovers.forEach((teleportedPopover) => {
185
+ containerB.append(teleportedPopover);
186
+ });
175
187
  },
176
188
  setState: function(state){
177
189
  return this.$refs.flow.setState(state);
@@ -189,7 +201,7 @@ export default {
189
201
  */
190
202
  setCurrentEntry: async function(state) {
191
203
  if (state && state.type) {
192
- if (state.type === "Scaffold" && state.url) {
204
+ if (state.type === "Scaffold" && (state.url || state.isBodyScaffold)) {
193
205
  //State for scaffold containing the following items:
194
206
  // label - Setting the name of the dialog
195
207
  // region - Which region/group currently focusing on
@@ -204,52 +216,67 @@ export default {
204
216
  state: state.state,
205
217
  viewUrl: state.viewUrl
206
218
  };
207
- // Add content from scicrunch for the context card
208
- const contextCardInfo = await this.retrieveContextCardFromUrl(state.url);
209
- newView = {...newView, ...contextCardInfo};
219
+ if (state.isBodyScaffold) {
220
+ const data = await getBodyScaffoldInfo(this.options.sparcApi, state.label);
221
+ newView = { ...newView, ...data.datasetInfo, resource: data.url };
222
+ } else {
223
+ // Add content from scicrunch for the context card
224
+ const contextCardInfo = await this.retrieveContextCardFromUrl(state.url);
225
+ newView = { ...newView, ...contextCardInfo };
226
+ }
210
227
  this.$refs.flow.createNewEntry(newView);
211
228
  } else if (state.type === "MultiFlatmap") {
212
- //State for scaffold containing the following items:
213
- // label - Setting the name of the dialog
214
- // taxo - taxo of species to set
215
- // biologicalSex - biological sex to be displayed (PATO)
216
- // organ - Target organ, flatmap will conduct a local search
217
- // using this
218
-
219
- //Look for the key in the available species array,
220
- //it will use the taxo and biologicalSex as hints.
221
- const key = findSpeciesKey(state);
222
- if (key) {
223
- const currentState = this.getState();
224
- if (currentState && currentState.entries) {
225
- for (let i = 0; i < currentState.entries.length; i++) {
226
- const entry = currentState.entries[i];
227
- if (entry.type === "MultiFlatmap") {
228
- entry.resource = key;
229
- entry.state = {species: key};
230
- if (state.organ || state.uuid) {
231
- entry.state.state = { searchTerm: state.organ, uuid: state.uuid };
232
- //if it contains an uuid, use the taxo to help identify if the uuid
233
- //is current
234
- if (state.uuid) entry.state.state.entry = state.taxo;
229
+ if (state.resource) {
230
+ //State for new multiflatmap containing the following items:
231
+ // label - Setting the name of the dialog
232
+ // resource - the url to metadata
233
+ // state - state to restore (viewport)
234
+ const newView = {
235
+ type: state.type,
236
+ resource: state.resource,
237
+ state: state.state,
238
+ label: state.label
239
+ };
240
+ this.$refs.flow.createNewEntry(newView);
241
+ } else {
242
+ //State for multiflatmap containing the following items:
243
+ // taxo - taxo of species to set
244
+ // biologicalSex - biological sex to be displayed (PATO)
245
+ // organ - Target organ, flatmap will conduct a local search
246
+ // using this
247
+
248
+ //Look for the key in the available species array,
249
+ //it will use the taxo and biologicalSex as hints.
250
+ const key = findSpeciesKey(state);
251
+ if (key) {
252
+ const currentState = this.getState();
253
+ if (currentState && currentState.entries) {
254
+ for (let i = 0; i < currentState.entries.length; i++) {
255
+ const entry = currentState.entries[i];
256
+ if (entry.type === "MultiFlatmap") {
257
+ entry.resource = key;
258
+ entry.state = { species: key };
259
+ if (state.organ || state.uuid) {
260
+ entry.state.state = { searchTerm: state.organ, uuid: state.uuid };
261
+ //if it contains an uuid, use the taxo to help identify if the uuid
262
+ //is current
263
+ if (state.uuid) entry.state.state.entry = state.taxo;
264
+ }
265
+ this.$refs.flow.setState(currentState);
266
+ //Do not create a new entry, instead set the multiflatmap viewer
267
+ //to the primary slot
268
+ this.$refs.flow.setIdToPrimaryPane(entry.id);
269
+ break;
235
270
  }
236
- this.$refs.flow.setState(currentState);
237
- //Do not create a new entry, instead set the multiflatmap viewer
238
- //to the primary slot
239
- this.$refs.flow.setIdToPrimaryPane(entry.id);
240
- break;
241
271
  }
242
272
  }
243
273
  }
244
274
  }
245
- }
246
- else if (state.type === "Flatmap") {
247
- //State for scaffold containing the following items:
275
+ } else if (state.type === "Flatmap") {
276
+ //State for flatmap containing the following items:
248
277
  // label - Setting the name of the dialog
249
- // region - Which region/group currently focusing on
250
278
  // resource - the url to metadata
251
279
  // state - state to restore (viewport)
252
- // viewUrl - relative path of the view file to metadata
253
280
  const newView = {
254
281
  type: state.type,
255
282
  resource: state.resource,
@@ -88,11 +88,11 @@ const capitalise = term => {
88
88
  */
89
89
  const availableSpecies = () => {
90
90
  return {
91
- "Human Female": { taxo: "NCBITaxon:9606", biologicalSex: "PATO:0000383", iconClass: "mapicon-icon_human", displayLatestChanges: true, displayWarning: true },
92
- "Human Male": { taxo: "NCBITaxon:9606", biologicalSex: "PATO:0000384", iconClass: "mapicon-icon_human", displayLatestChanges: true, displayWarning: true },
93
- "Rat": { taxo: "NCBITaxon:10114", iconClass: "mapicon-icon_rat", displayLatestChanges: true, displayWarning: true },
94
- "Mouse": { taxo: "NCBITaxon:10090", iconClass: "mapicon-icon_mouse", displayLatestChanges: true, displayWarning: true },
95
- "Pig": { taxo: "NCBITaxon:9823", iconClass: "mapicon-icon_pig", displayLatestChanges: true, displayWarning: true },
91
+ "Human Female": { taxo: "NCBITaxon:9606", biologicalSex: "PATO:0000383", iconClass: "mapicon-icon_human", displayLatestChanges: true, displayWarning: false },
92
+ "Human Male": { taxo: "NCBITaxon:9606", biologicalSex: "PATO:0000384", iconClass: "mapicon-icon_human", displayLatestChanges: true, displayWarning: false },
93
+ "Rat": { taxo: "NCBITaxon:10114", iconClass: "mapicon-icon_rat", displayLatestChanges: true, displayWarning: false },
94
+ "Mouse": { taxo: "NCBITaxon:10090", iconClass: "mapicon-icon_mouse", displayLatestChanges: true, displayWarning: false },
95
+ "Pig": { taxo: "NCBITaxon:9823", iconClass: "mapicon-icon_pig", displayLatestChanges: true, displayWarning: false },
96
96
  "Cat": { taxo: "NCBITaxon:9685", iconClass: "mapicon-icon_cat", displayLatestChanges: true, displayWarning: true },
97
97
  }
98
98
  }
@@ -3,6 +3,7 @@
3
3
  <FlatmapVuer
4
4
  :state="entry.state"
5
5
  :entry="entry.resource"
6
+ :mapManager="mapManager"
6
7
  @resource-selected="flatmaprResourceSelected(entry.type, $event)"
7
8
  @pan-zoom-callback="flatmapPanZoomCallback"
8
9
  :name="entry.resource"
@@ -32,6 +33,7 @@
32
33
  :sparcAPI="apiLocation"
33
34
  @open-map="openMap"
34
35
  @pathway-selection-changed="onPathwaySelectionChanged"
36
+ @mapmanager-loaded="onMapmanagerLoaded"
35
37
  />
36
38
 
37
39
  <HelpModeDialog
@@ -5,6 +5,7 @@
5
5
  @flatmapChanged="flatmapChanged"
6
6
  @ready="multiFlatmapReady"
7
7
  :state="entry.state"
8
+ :mapManager="mapManager"
8
9
  @resource-selected="flatmaprResourceSelected(entry.type, $event)"
9
10
  style="height: 100%; width: 100%"
10
11
  :initial="entry.resource"
@@ -33,6 +34,7 @@
33
34
  @finish-help-mode="endHelp"
34
35
  @pathway-selection-changed="onPathwaySelectionChanged"
35
36
  @open-pubmed-url="onOpenPubmedUrl"
37
+ @mapmanager-loaded="onMapmanagerLoaded"
36
38
  />
37
39
 
38
40
  <HelpModeDialog
@@ -450,8 +452,9 @@ export default {
450
452
  this.getFeaturedDatasets();
451
453
 
452
454
  EventBus.on('annotation-close', (payload) => {
453
- if (payload?.tabClose && this.$refs.multiflatmap.getCurrentFlatmap()) {
454
- this.$refs.multiflatmap.getCurrentFlatmap().annotationEventCallback({}, { type: 'aborted' })
455
+ if (payload?.tabClose && this.flatmapReady && this.$refs.multiflatmap) {
456
+ const currentFlatmap = this.$refs.multiflatmap.getCurrentFlatmap();
457
+ currentFlatmap.annotationEventCallback({}, { type: 'aborted' })
455
458
  }
456
459
  });
457
460
 
@@ -4,7 +4,6 @@ import {
4
4
  getParentsRegion,
5
5
  } from "../components/SimulatedData.js";
6
6
  import EventBus from "../components/EventBus";
7
- import markerZoomLevels from "../components/markerZoomLevelsHardCoded.js";
8
7
  import { mapStores } from 'pinia';
9
8
  import { useSettingsStore } from '../stores/settings';
10
9
  import { useSplitFlowStore } from '../stores/splitFlow';
@@ -77,6 +76,9 @@ export default {
77
76
 
78
77
  this.onConnectivityInfoClose();
79
78
  },
79
+ onMapmanagerLoaded: function (mapManager) {
80
+ this.settingsStore.updateMapManager(mapManager);
81
+ },
80
82
  trackOpenMap: function (category) {
81
83
  // GA Tagging
82
84
  // Open map tracking
@@ -123,16 +125,13 @@ export default {
123
125
  eventType: undefined,
124
126
  };
125
127
 
128
+
126
129
  if (type == "MultiFlatmap" || type == "Flatmap") {
127
- result.internalName = this.idNamePair[resource.feature.models];
130
+ result.internalName = resource?.feature?.label ? resource.feature.label : this.idNamePair[resource.feature.models];
128
131
  if (resource.eventType == "click") {
129
132
  result.eventType = "selected";
130
133
  if (resource.feature.type == "marker") {
131
- let label = this.idNamePair[resource.feature.models];
132
- let hardcodedAnnotation = markerZoomLevels.filter(
133
- mz => mz.id === resource.feature.models
134
- );
135
-
134
+ let label = result.internalName;
136
135
  if (
137
136
  this.settingsStore.isFeaturedMarkerIdentifier(
138
137
  resource.feature.id
@@ -146,15 +145,6 @@ export default {
146
145
  ),
147
146
  featuredDataset: true,
148
147
  };
149
- } else if (hardcodedAnnotation.filter(h => h.keyword).length > 0) {
150
- // if it matches our stored keywords, it is a keyword search
151
- // Keyword searches do not contain labels, so switch to keyword search if no label exists
152
- returnedAction = {
153
- type: "Search",
154
- term:
155
- "http://purl.obolibrary.org/obo/" +
156
- resource.feature.models.replace(":", "_"),
157
- };
158
148
  } else {
159
149
  // Facet search on anatomy if it is not a keyword search
160
150
  returnedAction = {
@@ -525,6 +515,7 @@ export default {
525
515
  scaffoldLoaded: false,
526
516
  isInHelp: false,
527
517
  hoverDelay: undefined,
518
+ mapManager: undefined,
528
519
  };
529
520
  },
530
521
  created: function () {
@@ -534,6 +525,9 @@ export default {
534
525
  this.flatmapAPI = this.settingsStore.flatmapAPI;
535
526
  if (this.settingsStore.sparcApi)
536
527
  this.apiLocation = this.settingsStore.sparcApi;
528
+ if (this.settingsStore.mapManager) {
529
+ this.mapManager = this.settingsStore.mapManager;
530
+ }
537
531
  },
538
532
  watch: {
539
533
  helpMode: function (newVal) {
@@ -1,9 +1,7 @@
1
1
 
2
- import markerZoomLevels from "../components/markerZoomLevelsHardCoded.js";
3
2
  import { mapStores } from 'pinia';
4
3
  import { useSettingsStore } from '../stores/settings';
5
4
 
6
-
7
5
  // remove duplicates by stringifying the objects
8
6
  const removeDuplicates = function (arrayOfAnything) {
9
7
  if (!arrayOfAnything) return []
@@ -77,8 +75,6 @@ export default {
77
75
  for (let j = 0; j < dataset.terms.length; j++) {
78
76
  if (fma.includes(dataset.terms[j])) {
79
77
  datasetAdjusted.terms.push(dataset.terms[j]);
80
-
81
-
82
78
  }
83
79
  }
84
80
  markersOnFlatmap.push(datasetAdjusted);
@@ -14,6 +14,7 @@ export const useSettingsStore = defineStore('settings', {
14
14
  flatmapAPI: undefined,
15
15
  nlLinkPrefix: undefined,
16
16
  flatmapAPI2: "https://mapcore-demo.org/curation/flatmap/",
17
+ mapManager: undefined,
17
18
  rootUrl: undefined,
18
19
  facets: { species: [], gender: [], organ: [] },
19
20
  numberOfDatasetsForFacets: [],
@@ -67,6 +68,9 @@ export const useSettingsStore = defineStore('settings', {
67
68
  updateFlatmapAPI2(flatmapAPI2) {
68
69
  this.flatmapAPI2 = flatmapAPI2;
69
70
  },
71
+ updateMapManager(mapManager) {
72
+ this.mapManager = mapManager;
73
+ },
70
74
  updateNLLinkPrefix(nlLinkPrefix) {
71
75
  this.nlLinkPrefix = nlLinkPrefix;
72
76
  },