diff --git a/package-lock.json b/package-lock.json index 77a8ee6d..21f87098 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,15 @@ { "name": "@abi-software/flatmapvuer", - "version": "1.10.2", + "version": "1.10.3-beta.10", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@abi-software/flatmapvuer", - "version": "1.10.2", + "version": "1.10.3-beta.10", "license": "Apache-2.0", "dependencies": { - "@abi-software/map-utilities": "^1.6.0", + "@abi-software/map-utilities": "^1.6.1-beta.6", "@abi-software/sparc-annotation": "0.3.2", "@abi-software/svg-sprite": "^1.0.1", "@element-plus/icons-vue": "^2.3.1", @@ -46,9 +46,9 @@ } }, "node_modules/@abi-software/map-utilities": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@abi-software/map-utilities/-/map-utilities-1.6.0.tgz", - "integrity": "sha512-1Tf8bj5sWiVDXBXpTZSoJaI2oc2odXeP8xACNV+cXSBhaRcPh0LQOLQ7wcqwEZuK9v7krmZr71+6NVOY7Cn/Tg==", + "version": "1.6.1-beta.6", + "resolved": "https://registry.npmjs.org/@abi-software/map-utilities/-/map-utilities-1.6.1-beta.6.tgz", + "integrity": "sha512-cRFzvsZNNcV9FAFmxtTQ/YPPIOspb3IkeJOzvWEBBQSNA3Mda78hPio6fK3KvVltompbS2T7pypfr9M6ImbU2A==", "dependencies": { "@abi-software/svg-sprite": "^1.0.1", "@element-plus/icons-vue": "^2.3.1", diff --git a/package.json b/package.json index 27eb0800..58449fe1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@abi-software/flatmapvuer", - "version": "1.10.2", + "version": "1.10.3-beta.10", "license": "Apache-2.0", "files": [ "dist/*", @@ -44,7 +44,7 @@ "./src/*": "./src/*" }, "dependencies": { - "@abi-software/map-utilities": "^1.6.0", + "@abi-software/map-utilities": "^1.6.1-beta.6", "@abi-software/sparc-annotation": "0.3.2", "@abi-software/svg-sprite": "^1.0.1", "@element-plus/icons-vue": "^2.3.1", diff --git a/src/components.d.ts b/src/components.d.ts index 2799c294..974a7996 100644 --- a/src/components.d.ts +++ b/src/components.d.ts @@ -8,7 +8,6 @@ export {} declare module 'vue' { export interface GlobalComponents { DynamicLegends: typeof import('./components/legends/DynamicLegends.vue')['default'] - ElAutocomplete: typeof import('element-plus/es')['ElAutocomplete'] ElButton: typeof import('element-plus/es')['ElButton'] ElCheckbox: typeof import('element-plus/es')['ElCheckbox'] ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup'] @@ -24,7 +23,6 @@ declare module 'vue' { ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup'] ElRow: typeof import('element-plus/es')['ElRow'] ElSelect: typeof import('element-plus/es')['ElSelect'] - ElSwitch: typeof import('element-plus/es')['ElSwitch'] FlatmapVuer: typeof import('./components/FlatmapVuer.vue')['default'] MultiFlatmapVuer: typeof import('./components/MultiFlatmapVuer.vue')['default'] SelectionsGroup: typeof import('./components/SelectionsGroup.vue')['default'] diff --git a/src/components/FlatmapVuer.vue b/src/components/FlatmapVuer.vue index bf24dbeb..c450cd64 100644 --- a/src/components/FlatmapVuer.vue +++ b/src/components/FlatmapVuer.vue @@ -643,6 +643,9 @@ import { refreshFlatmapKnowledgeCache, getKnowledgeSource, getReferenceConnectivitiesByAPI, + filterPathsByOriginFromKnowledge, + filterPathsByDestinationFromKnowledge, + filterPathsByViaFromKnowledge, } from '../services/flatmapKnowledge.js' import { capitalise } from './utilities.js' import yellowstar from '../icons/yellowstar' @@ -651,7 +654,19 @@ import * as flatmap from 'https://cdn.jsdelivr.net/npm/@abi-software/flatmap-vie import { AnnotationService } from '@abi-software/sparc-annotation' import { mapState } from 'pinia' import { useMainStore } from '@/store/index' -import { DrawToolbar, Tooltip, TreeControls } from '@abi-software/map-utilities' +import { + queryPathsByOrigin, + queryPathsByViaLocation, + queryPathsByDestination, + extractOriginItems, + extractDestinationItems, + extractViaItems, + fetchLabels, + queryAllConnectedPaths, + DrawToolbar, + Tooltip, + TreeControls +} from '@abi-software/map-utilities' import '@abi-software/map-utilities/dist/style.css' import EventBus from './EventBus.js' @@ -751,7 +766,7 @@ export default { }, methods: { /** - * + * * @param filter format should follow #makeStyleFilter (flatmap-viewer) */ setVisibilityFilter: function (filter) { @@ -1323,6 +1338,13 @@ export default { * @arg {string} `pathId` or `anatomicalId` */ retrieveConnectedPaths: async function (payload, options = {}) { + // query all connected paths CQ + if (this.viewingMode === 'Neuron Connection' && this.connectionType.toLowerCase() === 'all') { + const sourceId = this.mapImp.uuid; + const connectedPaths = await queryAllConnectedPaths(this.flatmapAPI, sourceId, payload); + return connectedPaths; + } + // query all connected paths from flatmap if (this.mapImp) { let connectedPaths = []; let connectedTarget = options.target?.length ? options.target : []; @@ -1411,8 +1433,8 @@ export default { const notPathways = { NOT: isPathways }; if (payload.key === "alert" || payload.key === "withoutAlert") { - const hasAlert = payload.key === "alert" ? - { HAS: 'alert' } : + const hasAlert = payload.key === "alert" ? + { HAS: 'alert' } : { NOT: { HAS: 'alert' } }; filter = { OR: [notPathways, { AND: [isPathways, hasAlert] }] }; @@ -1742,9 +1764,8 @@ export default { const clickedItem = singleSelection ? data : data[0] this.setConnectivityDataSource(this.viewingMode, clickedItem); if (this.viewingMode === 'Neuron Connection') { - this.retrieveConnectedPaths([clickedItem.models]).then((paths) => { - this.zoomToFeatures(paths) - }) + // do nothing here + // the method to highlight paths is moved to checkAndCreatePopups function } else { this.currentActive = clickedItem.models ? clickedItem.models : '' // This is for FC map // This is for annotation mode - draw connectivity between features/paths @@ -1777,7 +1798,6 @@ export default { data && data.type !== 'marker' && eventType === 'click' && - !(this.viewingMode === 'Neuron Connection') && // Disable popup when drawing !this.activeDrawTool ) { @@ -1923,7 +1943,18 @@ export default { this.emitConnectivityError(errorData); // highlight all available features - const featureIdsToHighlight = this.mapImp.modelFeatureIdList(featuresToHighlight); + const connectivityFeatures = featuresToHighlight.reduce((arr, path) => { + const connectivityObj = this.mapImp.pathways.paths[path]; + const connectivities = connectivityObj ? connectivityObj.connectivity : null; + if (connectivities) { + const flatFeatures = connectivities.flat(Infinity); + arr.push(...flatFeatures); + } + return arr; + }, []); + const uniqueConnectivityFeatures = [...new Set(connectivityFeatures)]; + const combinedFeatures = [...featuresToHighlight, ...uniqueConnectivityFeatures]; + const featureIdsToHighlight = this.mapImp.modelFeatureIdList(combinedFeatures); const allFeaturesToHighlight = [ ...featureIdsToHighlight, ...geojsonHighlights @@ -1948,6 +1979,14 @@ export default { } return featureIds; }, + getFlatmapKnowledge: function () { + let flatmapKnowledge = []; + const flatmapKnowledgeRaw = sessionStorage.getItem('flatmap-knowledge'); + if (flatmapKnowledgeRaw) { + flatmapKnowledge = JSON.parse(flatmapKnowledgeRaw); + } + return flatmapKnowledge; + }, emitConnectivityError: function (errorData) { this.$emit('connectivity-error', { data: { @@ -1983,7 +2022,7 @@ export default { * _checkNeuronClicked shows a neuron path pop up if a path was recently clicked._ * @arg {Object} `data` */ - checkAndCreatePopups: async function (data) { + checkAndCreatePopups: async function (data, connectivityExplorerClicked) { // Call flatmap database to get the connection data if (this.viewingMode === 'Annotation') { const features = data.filter(d => d.feature).map(d => d.feature) @@ -2030,6 +2069,95 @@ export default { } else { this.annotation = {} } + } + // clicking on a connectivity explorer card will be the same as exploration mode + // the card should be opened without doing other functions + else if (this.viewingMode === 'Neuron Connection' && !connectivityExplorerClicked) { + const resources = data.map(tooltip => tooltip.resource[0]); + + // filter out paths + const featureId = resources.find(resource => !resource.startsWith('ilxtr:')); + if (featureId) { + // fallback if it cannot find in anatomical nodes + const transformResources = Array.isArray(resources) ? [...resources] : [resources]; + if (transformResources.length === 1) { + transformResources.push([]); + } + + const featureId = data[0].feature?.featureId; + const annotation = this.mapImp.annotations.get(featureId); + const anatomicalNodes = annotation?.['anatomical-nodes']; + let anatomicalNode; + let uniqueResource = transformResources; + const models = annotation?.['models']; + if (anatomicalNodes?.length) { + anatomicalNode = anatomicalNodes[anatomicalNodes.length - 1]; + } + if (anatomicalNode) { + uniqueResource = JSON.parse(anatomicalNode); + } else if (models) { + uniqueResource = [models, []]; + } + + const terms = uniqueResource.flat(Infinity); + const uniqueTerms = [...new Set(terms)]; + const fetchResults = await fetchLabels(this.flatmapAPI, uniqueTerms); + const objectResults = fetchResults.reduce((arr, item) => { + const id = item[0]; + const valObj = JSON.parse(item[1]); + if (valObj.source === this.mapImp.knowledgeSource) { + arr.push({ id, label: valObj.label }); + } + return arr; + }, []); + const labels = []; + for (let i = 0; i < uniqueTerms.length; i++) { + const foundObj = objectResults.find((obj) => obj.id === uniqueTerms[i]) + if (foundObj) { + labels.push(foundObj.label); + } + } + const filterItemLabel = capitalise(labels.join(', ')); + const newConnectivityfilter = { + facet: JSON.stringify(uniqueResource), + facetPropPath: `flatmap.connectivity.source.${this.connectionType.toLowerCase()}`, + tagLabel: filterItemLabel, // used tagLabel here instead of label since the label and value are different + term: this.connectionType + }; + // check for existing item + const isNewFilterItemExist = this.connectivityFilters.some((connectivityfilter) => ( + connectivityfilter.facet === newConnectivityfilter.facet && + connectivityfilter.facetPropPath === newConnectivityfilter.facetPropPath + )); + + if (!isNewFilterItemExist) { + this.connectivityFilters.push(newConnectivityfilter); + } + + if (this.connectionType.toLowerCase() === 'all') { + const searchTerms = uniqueTerms.join(); + this.$emit('neuron-connection-feature-click', { + filters: [], + search: searchTerms, + }); + } else { + this.$emit('neuron-connection-feature-click', { + filters: this.connectivityFilters, + search: '', + }); + } + } else { + // clicking on paths + // do nothing for origin, destination, via + const searchTerms = resources.join(); + + if (this.connectionType.toLowerCase() === 'all') { + this.$emit('neuron-connection-feature-click', { + filters: [], + search: searchTerms, + }); + } + } } else { // load and store knowledge loadAndStoreKnowledge(this.mapImp, this.flatmapQueries); @@ -2044,6 +2172,7 @@ export default { // this should only for flatmap paths not all features if (this.tooltipEntry.length) { this.$emit('connectivity-info-open', this.tooltipEntry); + // While having placeholders displayed, get details for all paths and then replace. for (let index = 0; index < data.length; index++) { prom1.push(await this.getKnowledgeTooltip(data[index])) @@ -2056,6 +2185,31 @@ export default { } } }, + /** + * Updates the connectivity filters in flatmap when there are changes in the sidebar. + * @public + * @param {Array} payload - The array of filter items to update. + */ + updateConnectivityFilters: function (payload) { + if (!payload.length) return; + this.connectivityFilters = payload.filter((filterItem) => ( + filterItem.facet.toLowerCase() !== 'show all' + )); + }, + resetConnectivityfilters: function (payload) { + if (payload.length) { + // remove not found items + this.connectivityFilters = this.connectivityFilters.filter((connectivityfilter) => + payload.some((notFoundItem) => ( + notFoundItem.facetPropPath === connectivityfilter.facetPropPath && + notFoundItem.facet !== connectivityfilter.facet + )) + ) + } else { + // full reset + this.connectivityFilters = []; + } + }, getKnowledgeTooltip: async function (data) { //require data.resource && data.feature.source const results = await this.flatmapQueries.retrieveFlatmapKnowledgeForEvent(this.mapImp, data) @@ -2759,9 +2913,9 @@ export default { } return filterSources }, - getFilterOptions: async function () { + getFilterOptions: async function (providedKnowledge) { + let filterOptions = []; if (this.mapImp) { - let filterOptions = [] const filterRanges = this.mapImp.featureFilterRanges() for (const [key, value] of Object.entries(filterRanges)) { let main = { @@ -2814,8 +2968,79 @@ export default { filterOptions.push(main) } } - return filterOptions + const connectionFilters = []; + const baseFlatmapKnowledge = providedKnowledge || this.getFlatmapKnowledge(); + const mapKnowledge = this.mapImp.pathways.paths; + const flatmapKnowledge = baseFlatmapKnowledge.reduce((arr, knowledge) => { + const id = knowledge.id; + if (id) { + const mapKnowledgeObj = mapKnowledge[id]; + if (mapKnowledgeObj && mapKnowledgeObj.connectivity && mapKnowledgeObj['node-phenotypes']) { + const mapConnectivity = mapKnowledgeObj.connectivity; + const mapNodePhenotypes = mapKnowledgeObj['node-phenotypes']; + // take only map connectivity + knowledge.connectivity = [...mapConnectivity]; + for (let key in knowledge['node-phenotypes']) { + if (mapNodePhenotypes[key]) { + // take only map node-phenotypes + knowledge['node-phenotypes'][key] = [...mapNodePhenotypes[key]]; + } + } + // to avoid mutation + arr.push(JSON.parse(JSON.stringify(knowledge))); + } + } + return arr; + }, []); + const knowledgeSource = this.mapImp.knowledgeSource; + const originItems = await extractOriginItems(this.flatmapAPI, knowledgeSource, flatmapKnowledge); + const viaItems = await extractViaItems(this.flatmapAPI, knowledgeSource, flatmapKnowledge); + const destinationItems = await extractDestinationItems(this.flatmapAPI, knowledgeSource, flatmapKnowledge); + + const transformItem = (facet, item) => { + const key = JSON.stringify(item.key); + return { + key: `flatmap.connectivity.source.${facet}.${key}`, + label: item.label || key + }; + } + + for (const facet of ["origin", "via", "destination"]) { + let childrenList = [] + if (facet === 'origin') { + childrenList = originItems.map((item) => transformItem(facet, item)); + } else if (facet === 'via') { + childrenList = viaItems.map((item) => transformItem(facet, item)); + } else if (facet === 'destination') { + childrenList = destinationItems.map((item) => transformItem(facet, item)); + } + + // Those without label but key should be below + childrenList = childrenList.sort((a, b) => { + const isAlpha = (str) => /^[a-zA-Z]/.test(str); + const aAlpha = isAlpha(a.label); + const bAlpha = isAlpha(b.label); + + if (aAlpha && !bAlpha) return -1; + if (!aAlpha && bAlpha) return 1; + + return a.label.localeCompare(b.label); + }); + + if (childrenList.length) { + connectionFilters.push({ + key: `flatmap.connectivity.source.${facet}`, + label: facet, + children: childrenList, + }) + } + } + + if (connectionFilters.length) { + filterOptions.push(...connectionFilters) + } } + return filterOptions; }, /** * @public @@ -2893,7 +3118,7 @@ export default { * @arg {String} `term`, * @arg {String} `displayInfo` */ - searchAndShowResult: function (term, displayInfo) { + searchAndShowResult: function (term, displayInfo, connectivityExplorerClicked) { if (this.mapImp) { if (term === undefined || term === '') { this.mapImp.clearSearchResults() @@ -2924,13 +3149,8 @@ export default { provenanceTaxonomy: feature.taxons, alert: feature.alert, } - if (this.viewingMode === "Exploration" || this.viewingMode === "Annotation") { - this.checkAndCreatePopups([data]) - } else if (this.viewingMode === 'Neuron Connection') { - this.retrieveConnectedPaths(data.resource).then((paths) => { - this.zoomToFeatures(paths) - }) - } + // Show popup for all modes + this.checkAndCreatePopups([data], connectivityExplorerClicked) this.mapImp.showPopup(featureId, capitalise(feature.label), { className: 'custom-popup', positionAtLastClick: false, @@ -2945,6 +3165,21 @@ export default { } return false }, + /** + * @public + * Public method to highlight connected paths for neuron connection mode, + * to highlight paths for other display maps on spit screen. + * @arg {Array} `paths` + */ + highlightConnectedPaths: function (paths) { + if (paths.length) { + // filter paths for this map + const filteredPaths = paths.filter(path => (path in this.mapImp.pathways.paths)) + // this.zoomToFeatures is replaced with selectGeoJSONFeatures to highlight paths + const featureIdsToHighlight = this.mapImp.modelFeatureIdList(filteredPaths); + this.mapImp.selectGeoJSONFeatures(featureIdsToHighlight); + } + }, /** * @public * Function to show search suggestions @@ -2958,6 +3193,9 @@ export default { onActionClick: function (data) { EventBus.emit('onActionClick', data) }, + setConnectionType: function (type) { + this.connectionType = type; + }, }, props: { /** @@ -3257,6 +3495,7 @@ export default { 'Neuron Connection': 'Discover Neuron connections by selecting a neuron and viewing its associated network connections', 'Annotation': ['View feature annotations', 'Add, comment on and view feature annotations'] }, + connectionType: 'All', offlineAnnotationEnabled: false, offlineAnnotations: [], annotationFrom: 'Anyone', @@ -3303,6 +3542,7 @@ export default { }), searchTerm: "", taxonLeaveDelay: undefined, + connectivityFilters: [], flatmapLegends: [], } }, diff --git a/src/components/MultiFlatmapVuer.vue b/src/components/MultiFlatmapVuer.vue index 336695a5..546e9e18 100644 --- a/src/components/MultiFlatmapVuer.vue +++ b/src/components/MultiFlatmapVuer.vue @@ -70,6 +70,7 @@ @connectivity-info-open="onConnectivityInfoOpen" @connectivity-info-close="onConnectivityInfoClose" @connectivity-error="onConnectivityError" + @neuron-connection-feature-click="onNeuronConnectionFeatureClick" @open-map="$emit('open-map', $event)" @pathway-selection-changed="onSelectionsDataChanged" :minZoom="minZoom" @@ -305,6 +306,9 @@ export default { onConnectivityError: function (errorInfo) { this.$emit('connectivity-error', errorInfo); }, + onNeuronConnectionFeatureClick: function (payload) { + this.$emit('neuron-connection-feature-click', payload); + }, onSelectionsDataChanged: function (data) { this.$emit('pathway-selection-changed', data); }, @@ -557,6 +561,10 @@ export default { let map = this.getCurrentFlatmap() map.changeViewingMode(modeName) }, + setConnectionType: function (type) { + let map = this.getCurrentFlatmap(); + map.setConnectionType(type); + }, }, props: { /** diff --git a/src/services/flatmapKnowledge.js b/src/services/flatmapKnowledge.js index 9fec2d76..6e45bcba 100644 --- a/src/services/flatmapKnowledge.js +++ b/src/services/flatmapKnowledge.js @@ -1,3 +1,9 @@ +import { + findPathsByOriginItem, + findPathsByDestinationItem, + findPathsByViaItem, +} from '@abi-software/map-utilities'; + async function getReferenceConnectivitiesFromStorage(resource) { const flatmapKnowledgeRaw = sessionStorage.getItem('flatmap-knowledge'); @@ -26,6 +32,43 @@ async function getReferenceConnectivitiesByAPI(mapImp, resource, flatmapQueries) return featureIds; } +function getFlatmapKnowledge() { + const flatmapKnowledgeRaw = sessionStorage.getItem('flatmap-knowledge'); + + if (flatmapKnowledgeRaw) { + const flatmapKnowledge = JSON.parse(flatmapKnowledgeRaw); + return flatmapKnowledge; + } + return []; +} + +async function filterPathsByOriginFromKnowledge(resource) { + const flatmapKnowledge = getFlatmapKnowledge(); + const results = findPathsByOriginItem(flatmapKnowledge, resource); + if (Array.isArray(results)) { + return results.map(x => x.id); + } + return []; +} + +async function filterPathsByDestinationFromKnowledge(resource) { + const flatmapKnowledge = getFlatmapKnowledge(); + const results = findPathsByDestinationItem(flatmapKnowledge, resource); + if (Array.isArray(results)) { + return results.map(x => x.id); + } + return []; +} + +async function filterPathsByViaFromKnowledge(resource) { + const flatmapKnowledge = getFlatmapKnowledge(); + const results = findPathsByViaItem(flatmapKnowledge, resource); + if (Array.isArray(results)) { + return results.map(x => x.id); + } + return []; +} + function getKnowledgeSource(mapImp) { return getKnowledgeSourceFromProvenance(mapImp.provenance); } @@ -103,4 +146,7 @@ export { getKnowledgeSource, getKnowledgeSourceFromProvenance, refreshFlatmapKnowledgeCache, + filterPathsByOriginFromKnowledge, + filterPathsByDestinationFromKnowledge, + filterPathsByViaFromKnowledge, } diff --git a/src/services/flatmapQueries.js b/src/services/flatmapQueries.js index cf872caa..4e6e5f7b 100644 --- a/src/services/flatmapQueries.js +++ b/src/services/flatmapQueries.js @@ -103,7 +103,8 @@ let FlatmapQueries = function () { this.controller = undefined this.uberons = [] this.lookUp = [] - this.connectivitySource = 'sckan' + this.connectivitySource = 'map' // 'sckan' + this.noMapConnectivity = false } this.createTooltipData = async function (mapImp, eventData) { @@ -144,7 +145,8 @@ let FlatmapQueries = function () { hyperlinks: hyperlinks, provenanceTaxonomy: eventData.provenanceTaxonomy, provenanceTaxonomyLabel: taxonomyLabel, - connectivitySource: this.connectivitySource + connectivitySource: this.connectivitySource, + noMapConnectivity: this.noMapConnectivity, } return tooltipData } @@ -158,7 +160,8 @@ let FlatmapQueries = function () { componentsWithDatasets: this.componentsWithDatasets, destinations: this.destinations, destinationsWithDatasets: this.destinationsWithDatasets, - connectivitySource: this.connectivitySource + connectivitySource: this.connectivitySource, + noMapConnectivity: this.noMapConnectivity, }; } @@ -290,7 +293,7 @@ let FlatmapQueries = function () { return results } - this.queryForConnectivityNew = function (mapImp, keastId, connectivitySource = 'sckan', processConnectivity = true) { + this.queryForConnectivityNew = function (mapImp, keastId, connectivitySource = 'map', processConnectivity = true) { this.connectivitySource = connectivitySource return new Promise((resolve) => { const queryAPI = connectivitySource === 'map' @@ -300,6 +303,9 @@ let FlatmapQueries = function () { queryAPI .then((response) => { if (this.checkConnectivityExists(response)) { + if (connectivitySource === 'map') { + this.noMapConnectivity = false; + } let connectivity = response; if (processConnectivity) { this.processConnectivity(mapImp, connectivity).then((processedConnectivity) => { @@ -312,6 +318,32 @@ let FlatmapQueries = function () { }) } else resolve(connectivity) + } else if (connectivitySource === 'map') { + // switch to SCKAN + // when there has no connectivity data from Map + // and add the noMapConnectivity flag to disable the option + this.connectivitySource = 'sckan'; + this.noMapConnectivity = true; + mapImp.queryKnowledge(keastId) + .then((fallbackResponse) => { + if (this.checkConnectivityExists(fallbackResponse)) { + let connectivity = fallbackResponse; + if (processConnectivity) { + this.processConnectivity(mapImp, connectivity).then((processedConnectivity) => { + // response.references is publication urls + if (fallbackResponse.references) { + // with publications from both PubMed and Others + this.rawURLs = [...fallbackResponse.references]; + } + resolve(processedConnectivity) + }) + } + else resolve(connectivity) + } else { + resolve(false) + } + }) + .catch(() => resolve(false)); } else { resolve(false) }