From eb301ba32f7120a01848ad6383dce5388f2fd856 Mon Sep 17 00:00:00 2001 From: Dario Beraldi Date: Wed, 6 Nov 2024 02:42:02 +0000 Subject: [PATCH] Display message if sequence ontology is unavailable (#453) (#459) * Display message if sequence ontology is unavailable (#453) * Use Alert component * Better ontology loading error handling --------- Co-authored-by: Garrett Stevens --- .../OntologyManager/OntologyStore/index.ts | 35 ++++++++++++------- .../OntologyStore/indexeddb-storage.ts | 11 ++++-- .../src/makeDisplayComponent.tsx | 23 +++++++++++- 3 files changed, 53 insertions(+), 16 deletions(-) diff --git a/packages/jbrowse-plugin-apollo/src/OntologyManager/OntologyStore/index.ts b/packages/jbrowse-plugin-apollo/src/OntologyManager/OntologyStore/index.ts index 48fa34042..09763c1a2 100644 --- a/packages/jbrowse-plugin-apollo/src/OntologyManager/OntologyStore/index.ts +++ b/packages/jbrowse-plugin-apollo/src/OntologyManager/OntologyStore/index.ts @@ -7,7 +7,12 @@ import { UriLocation, isUriLocation, } from '@jbrowse/core/util' -import { IDBPTransaction, IndexNames, StoreNames } from 'idb/with-async-ittr' +import { + deleteDB, + IDBPTransaction, + IndexNames, + StoreNames, +} from 'idb/with-async-ittr' import { textSearch } from './fulltext' import { OntologyDB, OntologyDBEdge, isDeprecated } from './indexeddb-schema' @@ -176,18 +181,24 @@ export default class OntologyStore { return db } - const { sourceLocation, sourceType } = this - if (sourceType === 'obo-graph-json') { - await this.loadOboGraphJson(db) - } else { - throw new Error( - `ontology source file ${JSON.stringify( - sourceLocation, - )} has type ${sourceType}, which is not yet supported`, - ) - } + try { + const { sourceLocation, sourceType } = this + if (sourceType === 'obo-graph-json') { + await this.loadOboGraphJson(db) + } else { + throw new Error( + `ontology source file ${JSON.stringify( + sourceLocation, + )} has type ${sourceType}, which is not yet supported`, + ) + } - return db + return db + } catch (error) { + db.close() + await deleteDB(this.dbName) + throw error + } } async termCount(tx?: Transaction<['nodes']>) { diff --git a/packages/jbrowse-plugin-apollo/src/OntologyManager/OntologyStore/indexeddb-storage.ts b/packages/jbrowse-plugin-apollo/src/OntologyManager/OntologyStore/indexeddb-storage.ts index dff8b7edf..2e0beab78 100644 --- a/packages/jbrowse-plugin-apollo/src/OntologyManager/OntologyStore/indexeddb-storage.ts +++ b/packages/jbrowse-plugin-apollo/src/OntologyManager/OntologyStore/indexeddb-storage.ts @@ -84,9 +84,14 @@ export async function loadOboGraphJson(this: OntologyStore, db: Database) { // TODO: using file streaming along with an event-based json parser // instead of JSON.parse and .readFile could probably make this faster // and less memory intensive - const oboGraph = JSON.parse( - await openLocation(this.sourceLocation).readFile('utf8'), - ) as GraphDocument + let oboGraph: GraphDocument + try { + oboGraph = JSON.parse( + await openLocation(this.sourceLocation).readFile('utf8'), + ) as GraphDocument + } catch { + throw new Error('Error in loading ontology') + } const parseTime = Date.now() diff --git a/packages/jbrowse-plugin-apollo/src/makeDisplayComponent.tsx b/packages/jbrowse-plugin-apollo/src/makeDisplayComponent.tsx index 117e30fcd..6cb76a645 100644 --- a/packages/jbrowse-plugin-apollo/src/makeDisplayComponent.tsx +++ b/packages/jbrowse-plugin-apollo/src/makeDisplayComponent.tsx @@ -3,7 +3,7 @@ import PluginManager from '@jbrowse/core/PluginManager' import type LinearGenomeViewPlugin from '@jbrowse/plugin-linear-genome-view' import ExpandLessIcon from '@mui/icons-material/ExpandLess' import ExpandMoreIcon from '@mui/icons-material/ExpandMore' -import { Typography, alpha } from '@mui/material' +import { Alert, Typography, alpha } from '@mui/material' import { observer } from 'mobx-react' import React, { useCallback, useEffect, useRef } from 'react' import { makeStyles } from 'tss-react/mui' @@ -14,6 +14,9 @@ import { TrackLines } from './SixFrameFeatureDisplay/components' import { SixFrameFeatureDisplay } from './SixFrameFeatureDisplay/stateModel' import { TabularEditorPane } from './TabularEditor' +import { getSession } from '@jbrowse/core/util' +import { ApolloSessionModel } from './session' + const accordionControlHeight = 12 const useStyles = makeStyles()((theme) => ({ @@ -52,6 +55,11 @@ const useStyles = makeStyles()((theme) => ({ // position: 'relative', userSelect: 'none', }, + alertContainer: { + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + }, })) function scrollSelectedFeatureIntoView( @@ -155,6 +163,11 @@ export const DisplayComponent = observer(function DisplayComponent({ }: { model: LinearApolloDisplayI }) { + const session = getSession(model) as unknown as ApolloSessionModel + const { ontologyManager } = session.apolloDataStore + const { featureTypeOntology } = ontologyManager + const ontologyStore = featureTypeOntology?.dataStore + const { classes } = useStyles() const { @@ -177,6 +190,14 @@ export const DisplayComponent = observer(function DisplayComponent({ model.setDetailsHeight(detailsHeight - delta) } + if (!ontologyStore) { + return ( +
+ Could not load feature type ontology. +
+ ) + } + if (graphical && table) { const tabularHeight = tabularEditor.isShown ? detailsHeight : 0 const featureAreaHeight = isShown