@abi-software/mapintegratedvuer 0.7.1-demo.0 → 0.7.2-vue3.0-alpha.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 (65) hide show
  1. package/LICENSE +201 -201
  2. package/README.md +150 -142
  3. package/assets/gazelle-icons-no-background.css +32 -0
  4. package/assets/styleguide.css +19 -19
  5. package/cypress.config.js +23 -23
  6. package/dist/index.html +17 -17
  7. package/dist/mapintegratedvuer.js +60394 -59859
  8. package/dist/mapintegratedvuer.umd.cjs +515 -907
  9. package/dist/matterport.pdf +0 -0
  10. package/dist/style.css +1 -1
  11. package/dist/test.txt +0 -0
  12. package/package.json +135 -136
  13. package/public/index.html +17 -17
  14. package/public/matterport.pdf +0 -0
  15. package/public/test.txt +0 -0
  16. package/q.json +690 -0
  17. package/reporter-config.json +9 -9
  18. package/src/App.vue +245 -245
  19. package/src/assets/_variables.scss +43 -43
  20. package/src/assets/fonts/mapicon-species.eot +0 -0
  21. package/src/assets/fonts/mapicon-species.ttf +0 -0
  22. package/src/assets/fonts/mapicon-species.woff +0 -0
  23. package/src/assets/header-icon.scss +67 -67
  24. package/src/assets/mapicon-species-style.css +41 -41
  25. package/src/assets/styles.scss +9 -9
  26. package/src/components/ContentBar.vue +376 -376
  27. package/src/components/ContentVuer.vue +217 -217
  28. package/src/components/ContextCard.vue +385 -385
  29. package/src/components/ContextHelp.vue +73 -73
  30. package/src/components/CustomSplitter.vue +151 -151
  31. package/src/components/DatasetHeader.vue +97 -97
  32. package/src/components/DialogToolbarContent.vue +464 -464
  33. package/src/components/EventBus.js +3 -3
  34. package/src/components/FlatmapContextCard.vue +134 -134
  35. package/src/components/MapContent.vue +333 -285
  36. package/src/components/ResizeSensor.vue +47 -47
  37. package/src/components/SearchControls.vue +115 -115
  38. package/src/components/SimulatedData.js +721 -721
  39. package/src/components/SplitDialog.vue +287 -287
  40. package/src/components/SplitFlow.vue +414 -414
  41. package/src/components/index.js +7 -7
  42. package/src/components/markerZoomLevelsHardCoded.js +255 -255
  43. package/src/components/scripts/utilities.js +173 -173
  44. package/src/components/viewers/Flatmap.vue +145 -145
  45. package/src/components/viewers/Iframe.vue +31 -31
  46. package/src/components/viewers/MultiFlatmap.vue +384 -384
  47. package/src/components/viewers/Plot.vue +23 -23
  48. package/src/components/viewers/Scaffold.vue +198 -198
  49. package/src/components/viewers/Simulation.vue +21 -21
  50. package/src/icons/yellowstar.js +1 -1
  51. package/src/main.js +32 -22
  52. package/src/mixins/ContentMixin.js +438 -438
  53. package/src/mixins/DynamicMarkerMixin.js +88 -88
  54. package/src/mixins/RetrieveContextCardMixin.js +82 -0
  55. package/src/mixins/S3Bucket.vue +37 -37
  56. package/src/stores/entries.js +40 -40
  57. package/src/stores/index.js +24 -16
  58. package/src/stores/settings.js +144 -144
  59. package/src/stores/splitFlow.js +523 -523
  60. package/static.json +7 -7
  61. package/tsconfig.json +19 -0
  62. package/vite.config.js +70 -66
  63. package/vite.static-build.js +12 -12
  64. package/vitest.workspace.js +3 -3
  65. package/vuese-generator.js +65 -0
@@ -1,438 +1,438 @@
1
- import {
2
- getAvailableTermsForSpecies,
3
- getInteractiveAction,
4
- getNerveNames,
5
- getParentsRegion,
6
- } from "../components/SimulatedData.js";
7
- import EventBus from "../components/EventBus";
8
- import markerZoomLevels from "../components/markerZoomLevelsHardCoded.js";
9
- import { mapStores } from 'pinia';
10
- import { useSettingsStore } from '../stores/settings';
11
- import { useSplitFlowStore } from '../stores/splitFlow';
12
-
13
- function capitalise(text) {
14
- return text[0].toUpperCase() + text.substring(1)
15
- }
16
-
17
- /* eslint-disable no-alert, no-console */
18
- export default {
19
- props: {
20
- /**
21
- * Object containing information for
22
- * the required viewing.
23
- */
24
- entry: Object,
25
- visible: {
26
- type: Boolean,
27
- default: true,
28
- },
29
- mouseHovered: {
30
- type: Boolean,
31
- default: false,
32
- },
33
- },
34
- computed: {
35
- ...mapStores(useSettingsStore, useSplitFlowStore),
36
- syncMode() {
37
- return this.splitFlowStore.syncMode;
38
- },
39
- },
40
- mounted: function () {
41
- EventBus.on("startHelp", () => {
42
- this.startHelp();
43
- });
44
- },
45
- methods: {
46
- toggleSyncMode: function () {
47
- return;
48
- },
49
- getState: function () {
50
- return undefined;
51
- },
52
- openMap: function (type) {
53
- if (type === "SYNC") {
54
- this.toggleSyncMode();
55
- } else {
56
- EventBus.emit("OpenNewMap", type);
57
- }
58
- },
59
- updateWithViewUrl: function() {
60
- return;
61
- },
62
- /**
63
- * Perform a local search on this contentvuer
64
- */
65
- search: function () {
66
- return false;
67
- },
68
- /**
69
- * Get a list of search suggestions on this contentvuer
70
- */
71
- searchSuggestions: function () {
72
- return;
73
- },
74
- /**
75
- * Callback when the vuers emit a selected event.
76
- */
77
- resourceSelected: function (type, resource, augmented) {
78
- // Skip processing if resources already has actions
79
- if (this.resourceHasAction(resource)) {
80
- EventBus.emit("PopoverActionClick", resource);
81
- return;
82
- }
83
-
84
- let returnedAction = undefined;
85
- let action = "none";
86
- let fireResourceSelected = false;
87
- const result = {
88
- paneIndex: this.entry.id,
89
- type: type,
90
- resource: resource,
91
- internalName: undefined,
92
- eventType: undefined,
93
- };
94
-
95
- if (type == "MultiFlatmap" || type == "Flatmap") {
96
- result.internalName = this.idNamePair[resource.feature.models];
97
- if (resource.eventType == "click") {
98
- result.eventType = "selected";
99
- if (resource.feature.type == "marker") {
100
- let label = this.idNamePair[resource.feature.models];
101
- let hardcodedAnnotation = markerZoomLevels.filter(
102
- mz => mz.id === resource.feature.models
103
- );
104
-
105
- if (
106
- this.settingsStore.isFeaturedMarkerIdentifier(
107
- resource.feature.id
108
- )
109
- ) {
110
- // It is a featured dataset search for DOI.
111
- returnedAction = {
112
- type: "Search",
113
- term: this.settingsStore.featuredMarkerDoi(
114
- resource.feature.id
115
- ),
116
- };
117
- } else if (hardcodedAnnotation.filter(h => h.keyword).length > 0) {
118
- // if it matches our stored keywords, it is a keyword search
119
- // Keyword searches do not contain labels, so switch to keyword search if no label exists
120
- returnedAction = {
121
- type: "Search",
122
- term:
123
- "http://purl.obolibrary.org/obo/" +
124
- resource.feature.models.replace(":", "_"),
125
- };
126
- } else {
127
- // Facet search on anatomy if it is not a keyword search
128
- returnedAction = {
129
- type: "Facet",
130
- facet: label,
131
- facetPropPath: "anatomy.organ.category.name",
132
- term: "Anatomical structure",
133
- };
134
- }
135
-
136
- fireResourceSelected = true;
137
- if (type == "MultiFlatmap") {
138
- const flatmap =
139
- this.$refs.multiflatmap.getCurrentFlatmap().mapImp;
140
- flatmap.clearSearchResults();
141
- }
142
- } else if (resource.feature.type == "feature") {
143
- // Do no open scaffold in sync map
144
- if (this.syncMode) {
145
- fireResourceSelected = true;
146
- } else {
147
- action = "scaffold";
148
- }
149
- }
150
- } else if (resource.eventType == "mouseenter") {
151
- result.eventType = "highlighted";
152
- fireResourceSelected = true;
153
- }
154
- } else if (type == "Scaffold") {
155
- if (resource && resource[0]) {
156
- result.internalName = resource[0].data.id;
157
- // Facet search if marker is clicked
158
- if (resource[0].data.lastActionOnMarker === true) {
159
- returnedAction = {
160
- type: "Facet",
161
- facet: capitalise(resource[0].data.id),
162
- facetPropPath: "anatomy.organ.category.name",
163
- term: "Anatomical structure",
164
- };
165
- }
166
- }
167
- result.eventType = "selected";
168
- fireResourceSelected = true;
169
- action = "search";
170
- }
171
- if ((returnedAction === undefined) && augmented) {
172
- returnedAction = getInteractiveAction(result, action);
173
- }
174
- if (returnedAction) EventBus.emit("PopoverActionClick", returnedAction);
175
- if (fireResourceSelected) this.$emit("resource-selected", result);
176
- },
177
- resourceHasAction: function (resource) {
178
- return (
179
- resource.type === "URL" ||
180
- resource.type === "Search" ||
181
- resource.type === "Neuron Search" ||
182
- resource.type == "Facet" ||
183
- resource.type == "Facets"
184
- );
185
- },
186
- /**
187
- * Check if this viewer is currently visible
188
- */
189
- isVisible: function() {
190
- const paneName = this.splitFlowStore.getPaneNameById(this.entry.id);
191
- return paneName !== undefined;
192
- },
193
- displayTooltip: function() {
194
- return;
195
- },
196
- /**
197
- * Get the term to zoom/highlight in a synchronisation event,
198
- * if it cannot be found in the map, it will perform several
199
- * calls to try to ge a valid name/id.
200
- */
201
- getNameAndIdFromSyncData: async function (data) {
202
- let name = data.internalName;
203
- if (name === undefined && data.resource) {
204
- name = data.resource.label;
205
- }
206
- let id = undefined;
207
- if (data.resource && data.resource.resource) {
208
- id = data.resource.resource[0];
209
- }
210
- if (this.entry.type === "Scaffold") {
211
- const objects = this.$refs.scaffold.findObjectsWithGroupName(name);
212
- // If a region is not found use a hardcoded list to determine
213
- // its parents region first
214
- if (objects.length === 0) {
215
- //Use nerve mapping
216
- if (data.resource && data.resource.feature) {
217
- const matched = getNerveNames(data.resource.feature.models);
218
- if (matched.length > 0) return matched;
219
- }
220
- let matched = getParentsRegion(name);
221
- if (matched) {
222
- return matched;
223
- }
224
- // Hardcoded list failed - use an endpoint to find its parents
225
- if (id && data.eventType === "selected") {
226
- return fetch(`${this.apiLocation}get-related-terms/${id}`)
227
- .then(response => response.json())
228
- .then(data => {
229
- if (data.uberon.array.length > 0) {
230
- name =
231
- data.uberon.array[0].name.charAt(0).toUpperCase() +
232
- data.uberon.array[0].name.slice(1);
233
- id = data.uberon.array[0].id.toUpperCase();
234
- return { id, name };
235
- }
236
- });
237
- }
238
- }
239
- } else if (this.entry.type === "MultiFlatmap") {
240
- if (name === "Bladder") {
241
- name = "Urinary Bladder";
242
- } else {
243
- const matched = getNerveNames(name);
244
- if (matched.length > 0) name = matched[0];
245
- }
246
- }
247
- return { id, name };
248
- },
249
- getDatasetAnatomyInfo: function (identifier) {
250
- fetch(`${this.apiLocation}dataset_info/anatomy?identifier=${identifier}`)
251
- .then(response => response.json())
252
- .then(data => {
253
- const resultPayload = data.result[0];
254
- let markerCurie;
255
- try {
256
- markerCurie = resultPayload.anatomy.organ[0].curie;
257
- } catch (error) {
258
- markerCurie = undefined;
259
- }
260
- let markerDoi;
261
- try {
262
- markerDoi = resultPayload.item.curie;
263
- } catch (error) {
264
- markerDoi = undefined;
265
- }
266
- let markerSpecies;
267
- try {
268
- let index = 0;
269
- let found = false;
270
- while (!found && index < resultPayload.organisms.subject.length) {
271
- const entry = resultPayload.organisms.subject[index];
272
- if (entry.species) {
273
- markerSpecies = entry.species.name;
274
- found = true;
275
- }
276
- index += 1;
277
- }
278
- } catch (error) {
279
- markerSpecies = undefined;
280
- }
281
- this.updateFeatureMarkers([markerCurie], undefined)
282
- this.settingsStore.updateFeaturedMarker({
283
- identifier,
284
- marker: markerCurie,
285
- doi: markerDoi,
286
- species: markerSpecies,
287
- });
288
- });
289
- },
290
- // Check if the old featured dataset api has any info
291
- oldFeaturedDatasetApiHasInfo: async function () {
292
- let response = await fetch(`${this.apiLocation}get_featured_datasets_identifiers`)
293
- let data = await response.json()
294
- if (!data.identifiers || data.identifiers.length == 0) {
295
- return false;
296
- } else {
297
- return data.identifiers;
298
- }
299
- },
300
- // Check if the new featured dataset api has any info
301
- newFeaturedDatasetApiHasInfo: async function () {
302
- let response = await fetch(`${this.apiLocation}get_featured_dataset`)
303
- let data = await response.json()
304
- if (!data.datasets || data.datasets.length == 0) {
305
- return false;
306
- } else {
307
- return data.datasets.map(d => d.id);
308
- }
309
- },
310
-
311
- /**
312
- * Get a list of featured datasets to display.
313
- */
314
- getFeaturedDatasets: async function () {
315
- let datasetIds = [];
316
-
317
- // Check the two api endpoints for featured datasets, old one first
318
- let oldInfo = await this.oldFeaturedDatasetApiHasInfo();
319
- if (oldInfo) datasetIds = oldInfo;
320
- else {
321
- let newInfo = await this.newFeaturedDatasetApiHasInfo();
322
- if (newInfo) datasetIds = newInfo;
323
- }
324
- // Update the store with the new list of featured datasets
325
- this.settingsStore.updateFeatured(datasetIds);
326
- datasetIds.forEach(element => {
327
- this.getDatasetAnatomyInfo(element)
328
- });
329
- },
330
- zoomToFeatures: function () {
331
- return;
332
- },
333
- handleSyncMouseEvent: async function (data) {
334
- let info = await this.getNameAndIdFromSyncData(data);
335
- if (data.eventType === "highlighted") {
336
- this.highlightFeatures(info);
337
- } else if (data.eventType === "selected") {
338
- this.displayTooltip(info);
339
- //this.zoomToFeatures(info, true);
340
- }
341
- },
342
- /**
343
- * Handle sync pan zoom event
344
- */
345
- handleSyncPanZoomEvent: function () {
346
- return;
347
- },
348
- highlightFeatures: function () {
349
- return;
350
- },
351
- receiveSynchronisedEvent: async function (data) {
352
- if (data.paneIndex !== this.entry.id) {
353
- if (data.eventType == "panZoom") {
354
- //this.handleSyncPanZoomEvent(data);
355
- } else {
356
- this.handleSyncMouseEvent(data);
357
- }
358
- } else {
359
- if (data.eventType == "selected") {
360
- let info = await this.getNameAndIdFromSyncData(data);
361
- this.zoomToFeatures(info, false);
362
- }
363
- }
364
- },
365
- requestSynchronisedEvent: function () {
366
- return;
367
- },
368
- getAvailableTerms: function () {
369
- //Use the default list of uberons before we get the list from
370
- //the api
371
- let terms = getAvailableTermsForSpecies();
372
- for (let i = 0; i < terms.length; i++) {
373
- this.idNamePair[terms[i].id] = terms[i].name;
374
- }
375
- if (this.apiLocation) {
376
- if (this._controller) this._controller.abort();
377
- this._controller = new AbortController();
378
- let signal = this._controller.signal;
379
- fetch(`${this.apiLocation}get-organ-curies`, {
380
- signal,
381
- })
382
- .then(response => response.json())
383
- .then(data => {
384
- this._controller = undefined;
385
- data.uberon.array.forEach(pair => {
386
- this.idNamePair[pair.id.toUpperCase()] =
387
- pair.name.charAt(0).toUpperCase() + pair.name.slice(1);
388
- });
389
- return;
390
- });
391
- }
392
- },
393
- flatmapMarkerZoomUpdate() {
394
- return;
395
- },
396
- onResize: function () {
397
- return;
398
- },
399
- startHelp: function () {
400
- if (this.isInHelp === false) {
401
- this.helpMode = true;
402
- window.addEventListener("mousedown", this.endHelp);
403
- this.isInHelp = true;
404
- }
405
- },
406
- endHelp: function () {
407
- window.removeEventListener("mousedown", this.endHelp);
408
- this.helpMode = false;
409
- setTimeout(() => {
410
- this.isInHelp = false;
411
- }, 200);
412
- },
413
- },
414
- data: function () {
415
- return {
416
- apiLocation: undefined,
417
- activeSpecies: "Rat",
418
- scaffoldCamera: undefined,
419
- mainStyle: {
420
- height: this.entry.datasetTitle ? "calc(100% - 30px)" : "100%",
421
- width: "100%",
422
- bottom: "0px",
423
- },
424
- helpMode: false,
425
- idNamePair: {},
426
- scaffoldLoaded: false,
427
- isInHelp: false,
428
- };
429
- },
430
- created: function () {
431
- this.flatmapAPI = undefined;
432
- this.apiLocation = undefined;
433
- if (this.settingsStore.flatmapAPI)
434
- this.flatmapAPI = this.settingsStore.flatmapAPI;
435
- if (this.settingsStore.sparcApi)
436
- this.apiLocation = this.settingsStore.sparcApi;
437
- },
438
- };
1
+ import {
2
+ getAvailableTermsForSpecies,
3
+ getInteractiveAction,
4
+ getNerveNames,
5
+ getParentsRegion,
6
+ } from "../components/SimulatedData.js";
7
+ import EventBus from "../components/EventBus";
8
+ import markerZoomLevels from "../components/markerZoomLevelsHardCoded.js";
9
+ import { mapStores } from 'pinia';
10
+ import { useSettingsStore } from '../stores/settings';
11
+ import { useSplitFlowStore } from '../stores/splitFlow';
12
+
13
+ function capitalise(text) {
14
+ return text[0].toUpperCase() + text.substring(1)
15
+ }
16
+
17
+ /* eslint-disable no-alert, no-console */
18
+ export default {
19
+ props: {
20
+ /**
21
+ * Object containing information for
22
+ * the required viewing.
23
+ */
24
+ entry: Object,
25
+ visible: {
26
+ type: Boolean,
27
+ default: true,
28
+ },
29
+ mouseHovered: {
30
+ type: Boolean,
31
+ default: false,
32
+ },
33
+ },
34
+ computed: {
35
+ ...mapStores(useSettingsStore, useSplitFlowStore),
36
+ syncMode() {
37
+ return this.splitFlowStore.syncMode;
38
+ },
39
+ },
40
+ mounted: function () {
41
+ EventBus.on("startHelp", () => {
42
+ this.startHelp();
43
+ });
44
+ },
45
+ methods: {
46
+ toggleSyncMode: function () {
47
+ return;
48
+ },
49
+ getState: function () {
50
+ return undefined;
51
+ },
52
+ openMap: function (type) {
53
+ if (type === "SYNC") {
54
+ this.toggleSyncMode();
55
+ } else {
56
+ EventBus.emit("OpenNewMap", type);
57
+ }
58
+ },
59
+ updateWithViewUrl: function() {
60
+ return;
61
+ },
62
+ /**
63
+ * Perform a local search on this contentvuer
64
+ */
65
+ search: function () {
66
+ return false;
67
+ },
68
+ /**
69
+ * Get a list of search suggestions on this contentvuer
70
+ */
71
+ searchSuggestions: function () {
72
+ return;
73
+ },
74
+ /**
75
+ * Callback when the vuers emit a selected event.
76
+ */
77
+ resourceSelected: function (type, resource, augmented) {
78
+ // Skip processing if resources already has actions
79
+ if (this.resourceHasAction(resource)) {
80
+ EventBus.emit("PopoverActionClick", resource);
81
+ return;
82
+ }
83
+
84
+ let returnedAction = undefined;
85
+ let action = "none";
86
+ let fireResourceSelected = false;
87
+ const result = {
88
+ paneIndex: this.entry.id,
89
+ type: type,
90
+ resource: resource,
91
+ internalName: undefined,
92
+ eventType: undefined,
93
+ };
94
+
95
+ if (type == "MultiFlatmap" || type == "Flatmap") {
96
+ result.internalName = this.idNamePair[resource.feature.models];
97
+ if (resource.eventType == "click") {
98
+ result.eventType = "selected";
99
+ if (resource.feature.type == "marker") {
100
+ let label = this.idNamePair[resource.feature.models];
101
+ let hardcodedAnnotation = markerZoomLevels.filter(
102
+ mz => mz.id === resource.feature.models
103
+ );
104
+
105
+ if (
106
+ this.settingsStore.isFeaturedMarkerIdentifier(
107
+ resource.feature.id
108
+ )
109
+ ) {
110
+ // It is a featured dataset search for DOI.
111
+ returnedAction = {
112
+ type: "Search",
113
+ term: this.settingsStore.featuredMarkerDoi(
114
+ resource.feature.id
115
+ ),
116
+ };
117
+ } else if (hardcodedAnnotation.filter(h => h.keyword).length > 0) {
118
+ // if it matches our stored keywords, it is a keyword search
119
+ // Keyword searches do not contain labels, so switch to keyword search if no label exists
120
+ returnedAction = {
121
+ type: "Search",
122
+ term:
123
+ "http://purl.obolibrary.org/obo/" +
124
+ resource.feature.models.replace(":", "_"),
125
+ };
126
+ } else {
127
+ // Facet search on anatomy if it is not a keyword search
128
+ returnedAction = {
129
+ type: "Facet",
130
+ facet: label,
131
+ facetPropPath: "anatomy.organ.category.name",
132
+ term: "Anatomical structure",
133
+ };
134
+ }
135
+
136
+ fireResourceSelected = true;
137
+ if (type == "MultiFlatmap") {
138
+ const flatmap =
139
+ this.$refs.multiflatmap.getCurrentFlatmap().mapImp;
140
+ flatmap.clearSearchResults();
141
+ }
142
+ } else if (resource.feature.type == "feature") {
143
+ // Do no open scaffold in sync map
144
+ if (this.syncMode) {
145
+ fireResourceSelected = true;
146
+ } else {
147
+ action = "scaffold";
148
+ }
149
+ }
150
+ } else if (resource.eventType == "mouseenter") {
151
+ result.eventType = "highlighted";
152
+ fireResourceSelected = true;
153
+ }
154
+ } else if (type == "Scaffold") {
155
+ if (resource && resource[0]) {
156
+ result.internalName = resource[0].data.id;
157
+ // Facet search if marker is clicked
158
+ if (resource[0].data.lastActionOnMarker === true) {
159
+ returnedAction = {
160
+ type: "Facet",
161
+ facet: capitalise(resource[0].data.id),
162
+ facetPropPath: "anatomy.organ.category.name",
163
+ term: "Anatomical structure",
164
+ };
165
+ }
166
+ }
167
+ result.eventType = "selected";
168
+ fireResourceSelected = true;
169
+ action = "search";
170
+ }
171
+ if ((returnedAction === undefined) && augmented) {
172
+ returnedAction = getInteractiveAction(result, action);
173
+ }
174
+ if (returnedAction) EventBus.emit("PopoverActionClick", returnedAction);
175
+ if (fireResourceSelected) this.$emit("resource-selected", result);
176
+ },
177
+ resourceHasAction: function (resource) {
178
+ return (
179
+ resource.type === "URL" ||
180
+ resource.type === "Search" ||
181
+ resource.type === "Neuron Search" ||
182
+ resource.type == "Facet" ||
183
+ resource.type == "Facets"
184
+ );
185
+ },
186
+ /**
187
+ * Check if this viewer is currently visible
188
+ */
189
+ isVisible: function() {
190
+ const paneName = this.splitFlowStore.getPaneNameById(this.entry.id);
191
+ return paneName !== undefined;
192
+ },
193
+ displayTooltip: function() {
194
+ return;
195
+ },
196
+ /**
197
+ * Get the term to zoom/highlight in a synchronisation event,
198
+ * if it cannot be found in the map, it will perform several
199
+ * calls to try to ge a valid name/id.
200
+ */
201
+ getNameAndIdFromSyncData: async function (data) {
202
+ let name = data.internalName;
203
+ if (name === undefined && data.resource) {
204
+ name = data.resource.label;
205
+ }
206
+ let id = undefined;
207
+ if (data.resource && data.resource.resource) {
208
+ id = data.resource.resource[0];
209
+ }
210
+ if (this.entry.type === "Scaffold") {
211
+ const objects = this.$refs.scaffold.findObjectsWithGroupName(name);
212
+ // If a region is not found use a hardcoded list to determine
213
+ // its parents region first
214
+ if (objects.length === 0) {
215
+ //Use nerve mapping
216
+ if (data.resource && data.resource.feature) {
217
+ const matched = getNerveNames(data.resource.feature.models);
218
+ if (matched.length > 0) return matched;
219
+ }
220
+ let matched = getParentsRegion(name);
221
+ if (matched) {
222
+ return matched;
223
+ }
224
+ // Hardcoded list failed - use an endpoint to find its parents
225
+ if (id && data.eventType === "selected") {
226
+ return fetch(`${this.apiLocation}get-related-terms/${id}`)
227
+ .then(response => response.json())
228
+ .then(data => {
229
+ if (data.uberon.array.length > 0) {
230
+ name =
231
+ data.uberon.array[0].name.charAt(0).toUpperCase() +
232
+ data.uberon.array[0].name.slice(1);
233
+ id = data.uberon.array[0].id.toUpperCase();
234
+ return { id, name };
235
+ }
236
+ });
237
+ }
238
+ }
239
+ } else if (this.entry.type === "MultiFlatmap") {
240
+ if (name === "Bladder") {
241
+ name = "Urinary Bladder";
242
+ } else {
243
+ const matched = getNerveNames(name);
244
+ if (matched.length > 0) name = matched[0];
245
+ }
246
+ }
247
+ return { id, name };
248
+ },
249
+ getDatasetAnatomyInfo: function (identifier) {
250
+ fetch(`${this.apiLocation}dataset_info/anatomy?identifier=${identifier}`)
251
+ .then(response => response.json())
252
+ .then(data => {
253
+ const resultPayload = data.result[0];
254
+ let markerCurie;
255
+ try {
256
+ markerCurie = resultPayload.anatomy.organ[0].curie;
257
+ } catch (error) {
258
+ markerCurie = undefined;
259
+ }
260
+ let markerDoi;
261
+ try {
262
+ markerDoi = resultPayload.item.curie;
263
+ } catch (error) {
264
+ markerDoi = undefined;
265
+ }
266
+ let markerSpecies;
267
+ try {
268
+ let index = 0;
269
+ let found = false;
270
+ while (!found && index < resultPayload.organisms.subject.length) {
271
+ const entry = resultPayload.organisms.subject[index];
272
+ if (entry.species) {
273
+ markerSpecies = entry.species.name;
274
+ found = true;
275
+ }
276
+ index += 1;
277
+ }
278
+ } catch (error) {
279
+ markerSpecies = undefined;
280
+ }
281
+ this.updateFeatureMarkers([markerCurie], undefined)
282
+ this.settingsStore.updateFeaturedMarker({
283
+ identifier,
284
+ marker: markerCurie,
285
+ doi: markerDoi,
286
+ species: markerSpecies,
287
+ });
288
+ });
289
+ },
290
+ // Check if the old featured dataset api has any info
291
+ oldFeaturedDatasetApiHasInfo: async function () {
292
+ let response = await fetch(`${this.apiLocation}get_featured_datasets_identifiers`)
293
+ let data = await response.json()
294
+ if (!data.identifiers || data.identifiers.length == 0) {
295
+ return false;
296
+ } else {
297
+ return data.identifiers;
298
+ }
299
+ },
300
+ // Check if the new featured dataset api has any info
301
+ newFeaturedDatasetApiHasInfo: async function () {
302
+ let response = await fetch(`${this.apiLocation}get_featured_dataset`)
303
+ let data = await response.json()
304
+ if (!data.datasets || data.datasets.length == 0) {
305
+ return false;
306
+ } else {
307
+ return data.datasets.map(d => d.id);
308
+ }
309
+ },
310
+
311
+ /**
312
+ * Get a list of featured datasets to display.
313
+ */
314
+ getFeaturedDatasets: async function () {
315
+ let datasetIds = [];
316
+
317
+ // Check the two api endpoints for featured datasets, old one first
318
+ let oldInfo = await this.oldFeaturedDatasetApiHasInfo();
319
+ if (oldInfo) datasetIds = oldInfo;
320
+ else {
321
+ let newInfo = await this.newFeaturedDatasetApiHasInfo();
322
+ if (newInfo) datasetIds = newInfo;
323
+ }
324
+ // Update the store with the new list of featured datasets
325
+ this.settingsStore.updateFeatured(datasetIds);
326
+ datasetIds.forEach(element => {
327
+ this.getDatasetAnatomyInfo(element)
328
+ });
329
+ },
330
+ zoomToFeatures: function () {
331
+ return;
332
+ },
333
+ handleSyncMouseEvent: async function (data) {
334
+ let info = await this.getNameAndIdFromSyncData(data);
335
+ if (data.eventType === "highlighted") {
336
+ this.highlightFeatures(info);
337
+ } else if (data.eventType === "selected") {
338
+ this.displayTooltip(info);
339
+ //this.zoomToFeatures(info, true);
340
+ }
341
+ },
342
+ /**
343
+ * Handle sync pan zoom event
344
+ */
345
+ handleSyncPanZoomEvent: function () {
346
+ return;
347
+ },
348
+ highlightFeatures: function () {
349
+ return;
350
+ },
351
+ receiveSynchronisedEvent: async function (data) {
352
+ if (data.paneIndex !== this.entry.id) {
353
+ if (data.eventType == "panZoom") {
354
+ //this.handleSyncPanZoomEvent(data);
355
+ } else {
356
+ this.handleSyncMouseEvent(data);
357
+ }
358
+ } else {
359
+ if (data.eventType == "selected") {
360
+ let info = await this.getNameAndIdFromSyncData(data);
361
+ this.zoomToFeatures(info, false);
362
+ }
363
+ }
364
+ },
365
+ requestSynchronisedEvent: function () {
366
+ return;
367
+ },
368
+ getAvailableTerms: function () {
369
+ //Use the default list of uberons before we get the list from
370
+ //the api
371
+ let terms = getAvailableTermsForSpecies();
372
+ for (let i = 0; i < terms.length; i++) {
373
+ this.idNamePair[terms[i].id] = terms[i].name;
374
+ }
375
+ if (this.apiLocation) {
376
+ if (this._controller) this._controller.abort();
377
+ this._controller = new AbortController();
378
+ let signal = this._controller.signal;
379
+ fetch(`${this.apiLocation}get-organ-curies`, {
380
+ signal,
381
+ })
382
+ .then(response => response.json())
383
+ .then(data => {
384
+ this._controller = undefined;
385
+ data.uberon.array.forEach(pair => {
386
+ this.idNamePair[pair.id.toUpperCase()] =
387
+ pair.name.charAt(0).toUpperCase() + pair.name.slice(1);
388
+ });
389
+ return;
390
+ });
391
+ }
392
+ },
393
+ flatmapMarkerZoomUpdate() {
394
+ return;
395
+ },
396
+ onResize: function () {
397
+ return;
398
+ },
399
+ startHelp: function () {
400
+ if (this.isInHelp === false) {
401
+ this.helpMode = true;
402
+ window.addEventListener("mousedown", this.endHelp);
403
+ this.isInHelp = true;
404
+ }
405
+ },
406
+ endHelp: function () {
407
+ window.removeEventListener("mousedown", this.endHelp);
408
+ this.helpMode = false;
409
+ setTimeout(() => {
410
+ this.isInHelp = false;
411
+ }, 200);
412
+ },
413
+ },
414
+ data: function () {
415
+ return {
416
+ apiLocation: undefined,
417
+ activeSpecies: "Rat",
418
+ scaffoldCamera: undefined,
419
+ mainStyle: {
420
+ height: this.entry.datasetTitle ? "calc(100% - 30px)" : "100%",
421
+ width: "100%",
422
+ bottom: "0px",
423
+ },
424
+ helpMode: false,
425
+ idNamePair: {},
426
+ scaffoldLoaded: false,
427
+ isInHelp: false,
428
+ };
429
+ },
430
+ created: function () {
431
+ this.flatmapAPI = undefined;
432
+ this.apiLocation = undefined;
433
+ if (this.settingsStore.flatmapAPI)
434
+ this.flatmapAPI = this.settingsStore.flatmapAPI;
435
+ if (this.settingsStore.sparcApi)
436
+ this.apiLocation = this.settingsStore.sparcApi;
437
+ },
438
+ };