import React, { useMemo, useState } from 'react' import { ErrorMessage } from '@jbrowse/core/ui' import DeleteIcon from '@mui/icons-material/Delete' import { Button, IconButton, List, ListItem, ListItemButton, ListItemText, Typography, } from '@mui/material' import { observer } from 'mobx-react' import { makeStyles } from 'tss-react/mui' import { blastLaunchViewFromCache } from './blastLaunchView' import { useCachedBlastResults } from './useCachedBlastResults' import { featureMatchesId, getGeneIdentifiers, getLinearGenomeView, getSortedTranscriptFeatures, } from '../../util' import type { CachedBlastResult } from '../../../utils/blastCache' import type { AbstractTrackModel, Feature } from '@jbrowse/core/util' const useStyles = makeStyles()({ header: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 8, }, resultList: { maxHeight: 300, overflow: 'auto', }, }) function getResultDisplayName(result: CachedBlastResult): string { const parts = [ result.geneName, result.transcriptName !== result.geneName ? result.transcriptName : undefined, ].filter((p): p is string => !!p) return parts.length > 0 ? parts.join(' - ') : (result.geneId ?? result.transcriptId ?? 'Unknown') } const CachedBlastResults = observer(function ({ model, handleClose, feature, }: { model: AbstractTrackModel handleClose: () => void feature: Feature }) { const { classes } = useStyles() const view = getLinearGenomeView(model) const [operationError, setOperationError] = useState() const geneIds = useMemo(() => getGeneIdentifiers(feature), [feature]) const { results, error, isLoading, handleDelete, handleClearAll } = useCachedBlastResults(geneIds) const handleUseCached = (cached: CachedBlastResult) => { // reconnect the cached MSA to the genome: the cached query row is named // 'QUERY' (react-msaview's default querySeqName) and corresponds to the // transcript stored as transcriptId. Resolving it here restores the // MSA<->genome navigation and hover-sync a fresh BLAST gets. const { transcriptId } = cached const transcript = transcriptId ? getSortedTranscriptFeatures(feature).find(t => featureMatchesId(t, transcriptId), ) : undefined blastLaunchViewFromCache({ view, cached, newViewTitle: `BLAST - ${getResultDisplayName(cached)}`, connectedFeature: transcript?.toJSON(), }) handleClose() } const displayError = error ?? operationError return displayError ? ( ) : isLoading ? ( Loading cached results... ) : results.length === 0 ? ( No cached BLAST results found for this gene. Run a BLAST query to cache results. ) : (
Cached BLAST Results ({results.length})
{results.map(result => ( { e.stopPropagation() try { setOperationError(undefined) await handleDelete(result.id) } catch (err) { setOperationError(err) } }} > } > { handleUseCached(result) }} > ))}
) }) export default CachedBlastResults