From 9b6cf972d0268f7eab73a9c86f1dc937f82df70d Mon Sep 17 00:00:00 2001 From: Shashank B R Date: Tue, 13 Aug 2024 19:07:55 +0100 Subject: [PATCH] Lint error fixes (#420) * fixes * fixes * A few type changes --------- Co-authored-by: Garrett Stevens --- .../src/GFF3/gff3ToAnnotationFeature.ts | 14 ++--- .../ApolloTranscriptDetailsWidget.tsx | 28 ++++----- .../FeatureDetailsWidget/TranscriptBasic.tsx | 57 ++++++++++++------- .../TranscriptSequence.tsx | 24 ++++---- .../src/FeatureDetailsWidget/model.ts | 11 +++- .../HybridGrid/featureContextMenuItems.ts | 34 +++++------ 6 files changed, 95 insertions(+), 73 deletions(-) diff --git a/packages/apollo-shared/src/GFF3/gff3ToAnnotationFeature.ts b/packages/apollo-shared/src/GFF3/gff3ToAnnotationFeature.ts index 8eafb3c58..f6afae157 100644 --- a/packages/apollo-shared/src/GFF3/gff3ToAnnotationFeature.ts +++ b/packages/apollo-shared/src/GFF3/gff3ToAnnotationFeature.ts @@ -50,14 +50,12 @@ export function gff3ToAnnotationFeature( if (type !== 'CDS') { throw new Error('GFF3 features has multiple locations but is not a CDS') } - const mins = gff3Feature - .map((f) => { - if (f.start === null) { - throw new Error(`feature does not have start: ${JSON.stringify(f)}`) - } - return f.start - 1 - }) - .filter((m): m is number => m !== null) + const mins = gff3Feature.map((f) => { + if (f.start === null) { + throw new Error(`feature does not have start: ${JSON.stringify(f)}`) + } + return f.start - 1 + }) const maxes = gff3Feature .map((f) => f.end) .filter((m): m is number => m !== null) diff --git a/packages/jbrowse-plugin-apollo/src/FeatureDetailsWidget/ApolloTranscriptDetailsWidget.tsx b/packages/jbrowse-plugin-apollo/src/FeatureDetailsWidget/ApolloTranscriptDetailsWidget.tsx index dde36ff38..b113cb3e7 100644 --- a/packages/jbrowse-plugin-apollo/src/FeatureDetailsWidget/ApolloTranscriptDetailsWidget.tsx +++ b/packages/jbrowse-plugin-apollo/src/FeatureDetailsWidget/ApolloTranscriptDetailsWidget.tsx @@ -1,7 +1,7 @@ -import { AnnotationFeature } from '@apollo-annotation/mst' +import { AnnotationFeature, ApolloRefSeqI } from '@apollo-annotation/mst' import { AbstractSessionModel, getSession, revcom } from '@jbrowse/core/util' import { observer } from 'mobx-react' -import { IAnyStateTreeNode, getRoot } from 'mobx-state-tree' +import { getRoot } from 'mobx-state-tree' import React from 'react' import { ApolloInternetAccountModel } from '../ApolloInternetAccount/model' @@ -10,6 +10,7 @@ import { ApolloRootModel } from '../types' import { Attributes } from './Attributes' import { TranscriptBasicInformation } from './TranscriptBasic' import { TranscriptSequence } from './TranscriptSequence' +import { ApolloTranscriptDetailsWidget as ApolloTranscriptDetailsWidgetState } from './model' export interface CDSInfo { id: string @@ -29,8 +30,7 @@ export interface ExonInfo { export const getCDSInfo = ( feature: AnnotationFeature, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - refData: any, + refData: ApolloRefSeqI, ): CDSInfo[] => { const CDSresult: CDSInfo[] = [] const traverse = ( @@ -64,8 +64,8 @@ export const getCDSInfo = ( max: (currentFeature.max + 1) as unknown as string, oldMin: (currentFeature.min + 1) as unknown as string, oldMax: (currentFeature.max + 1) as unknown as string, - startSeq: startSeq ?? '', - endSeq: endSeq ?? '', + startSeq: startSeq || '', + endSeq: endSeq || '', } CDSresult.push(oneCDS) } @@ -104,7 +104,9 @@ export const getCDSInfo = ( } export const ApolloTranscriptDetailsWidget = observer( - function ApolloTranscriptDetails(props: { model: IAnyStateTreeNode }) { + function ApolloTranscriptDetails(props: { + model: ApolloTranscriptDetailsWidgetState + }) { const { model } = props const { assembly, feature, refName } = model const session = getSession(model) as unknown as AbstractSessionModel @@ -126,12 +128,12 @@ export const ApolloTranscriptDetailsWidget = observer( if (!refSeq) { return null } - const { end, start } = feature + const { max, min } = feature - const sequence = refSeq.getSequence(start, end) + const sequence = refSeq.getSequence(min, max) if (!sequence) { void apolloSession.apolloDataStore.loadRefSeq([ - { assemblyName: assembly, refName, start, end }, + { assemblyName: assembly, refName, start: min, end: max }, ]) } @@ -140,21 +142,21 @@ export const ApolloTranscriptDetailsWidget = observer(

diff --git a/packages/jbrowse-plugin-apollo/src/FeatureDetailsWidget/TranscriptBasic.tsx b/packages/jbrowse-plugin-apollo/src/FeatureDetailsWidget/TranscriptBasic.tsx index 022741f6a..28656c876 100644 --- a/packages/jbrowse-plugin-apollo/src/FeatureDetailsWidget/TranscriptBasic.tsx +++ b/packages/jbrowse-plugin-apollo/src/FeatureDetailsWidget/TranscriptBasic.tsx @@ -19,13 +19,19 @@ import { NumberTextField } from './NumberTextField' * @param featureId - * @returns */ -function getFeatureFromId(feature: any, featureId: string): any | null { +function getFeatureFromId( + feature: AnnotationFeature, + featureId: string, +): AnnotationFeature | null { if (feature._id === featureId) { return feature } // Check if there is also childFeatures in parent feature and it's not empty // Let's get featureId from recursive method - for (const [, childFeature] of feature.children ?? new Map()) { + if (!feature.children) { + return null + } + for (const [, childFeature] of feature.children) { const subFeature = getFeatureFromId(childFeature, featureId) if (subFeature) { return subFeature @@ -106,11 +112,12 @@ export const TranscriptBasicInformation = observer( newStart, assembly, }) - return changeManager.submit(change) + changeManager.submit(change).catch(() => { + notify('Error updating feature start position') + }) } } } - return } function handleEndChange( @@ -123,7 +130,7 @@ export const TranscriptBasicInformation = observer( notify('Feature start cannot be greater than parent end', 'error') return } - if (subFeature.children) { + if (subFeature?.children) { // Let's check CDS start and end values. And possibly update those too for (const child of subFeature.children) { if ( @@ -138,11 +145,12 @@ export const TranscriptBasicInformation = observer( newEnd, assembly, }) - return changeManager.submit(change) + changeManager.submit(change).catch(() => { + notify('Error updating feature end position') + }) } } } - return } const featureNew = feature as unknown as AnnotationFeature @@ -188,8 +196,8 @@ export const TranscriptBasicInformation = observer( max: dataPoint.max as unknown as string, oldMin: (dataPoint.min + 1) as unknown as string, oldMax: dataPoint.max as unknown as string, - startSeq: startSeq ?? '', - endSeq: endSeq ?? '', + startSeq: startSeq || '', + endSeq: endSeq || '', } // CDSresult.push(oneCDS) // Check if there is already an object with the same start and end @@ -206,7 +214,7 @@ export const TranscriptBasicInformation = observer( } // Add possible UTRs - const foundExon = findExonInRange( + const foundExon: ExonInfo | null = findExonInRange( exonsArray, dataPoint.min + 1, dataPoint.max, @@ -231,9 +239,11 @@ export const TranscriptBasicInformation = observer( type: 'three_prime_UTR', strand: Number(feature.strand), min: (dataPoint.min + 1) as unknown as string, - max: foundExon.min + 1, + max: ((foundExon.min as unknown as number) + + 1) as unknown as string, oldMin: (dataPoint.min + 1) as unknown as string, - oldMax: foundExon.min + 1, + oldMax: ((foundExon.min as unknown as number) + + 1) as unknown as string, startSeq: '', endSeq: '', } @@ -302,9 +312,10 @@ export const TranscriptBasicInformation = observer( id: featureNew._id, type: 'five_prime_UTR', strand: Number(featureNew.strand), - min: (element.min + 1) as unknown as string, + min: ((element.min as unknown as number) + 1) as unknown as string, max: element.max, - oldMin: (element.min + 1) as unknown as string, + oldMin: ((element.min as unknown as number) + + 1) as unknown as string, oldMax: element.max, startSeq: '', endSeq: '', @@ -315,10 +326,12 @@ export const TranscriptBasicInformation = observer( id: featureNew._id, type: 'three_prime_UTR', strand: Number(featureNew.strand), - min: (element.min + 1) as unknown as string, - max: element.max + 1, - oldMin: (element.min + 1) as unknown as string, - oldMax: element.max + 1, + min: ((element.min as unknown as number) + 1) as unknown as string, + max: ((element.max as unknown as number) + 1) as unknown as string, + oldMin: ((element.min as unknown as number) + + 1) as unknown as string, + oldMax: ((element.max as unknown as number) + + 1) as unknown as string, startSeq: '', endSeq: '', } @@ -395,9 +408,9 @@ export const TranscriptBasicInformation = observer( }} variant="outlined" value={item.min} - onChangeCommitted={(newStart: number) => + onChangeCommitted={(newStart: number) => { handleStartChange(newStart, item.id, Number(item.oldMin)) - } + }} /> {item.strand === -1 ? '-' : item.strand === 1 ? '+' : ''} @@ -416,9 +429,9 @@ export const TranscriptBasicInformation = observer( }} variant="outlined" value={item.max} - onChangeCommitted={(newEnd: number) => + onChangeCommitted={(newEnd: number) => { handleEndChange(newEnd, item.id, Number(item.oldMax)) - } + }} /> {item.endSeq} diff --git a/packages/jbrowse-plugin-apollo/src/FeatureDetailsWidget/TranscriptSequence.tsx b/packages/jbrowse-plugin-apollo/src/FeatureDetailsWidget/TranscriptSequence.tsx index ff1db5ba9..810bdd0a7 100644 --- a/packages/jbrowse-plugin-apollo/src/FeatureDetailsWidget/TranscriptSequence.tsx +++ b/packages/jbrowse-plugin-apollo/src/FeatureDetailsWidget/TranscriptSequence.tsx @@ -1,4 +1,4 @@ -import { AnnotationFeature } from '@apollo-annotation/mst' +import { AnnotationFeature, ApolloRefSeqI } from '@apollo-annotation/mst' import { splitStringIntoChunks } from '@apollo-annotation/shared' import { revcom } from '@jbrowse/core/util' import { @@ -52,11 +52,11 @@ export const TranscriptSequence = observer(function TranscriptSequence({ session: ApolloSessionModel }) { const currentAssembly = session.apolloDataStore.assemblies.get(assembly) - const refData = currentAssembly?.getByRefName(refName) + const refData = currentAssembly?.getByRefName(refName) as ApolloRefSeqI const [showSequence, setShowSequence] = useState(false) const [selectedOption, setSelectedOption] = useState('Select') - if (!(feature && currentAssembly)) { + if (!currentAssembly) { return null } const refSeq = currentAssembly.getByRefName(refName) @@ -95,8 +95,8 @@ export const TranscriptSequence = observer(function TranscriptSequence({ textSegments.push({ text: `>${refName} : CDS\n`, color: 'black' }) for (const item of transcriptItems) { if (item.type === 'CDS') { - const refSeq: string | undefined = refData?.getSequence( - Number(item.min + 1), + const refSeq: string | undefined = refData.getSequence( + Number((item.min as unknown as number) + 1), Number(item.max), ) seqData += item.strand === -1 && refSeq ? revcom(refSeq) : refSeq @@ -113,8 +113,8 @@ export const TranscriptSequence = observer(function TranscriptSequence({ item.type === 'three_prime_UTR' || item.type === 'five_prime_UTR' ) { - const refSeq: string | undefined = refData?.getSequence( - Number(item.min + 1), + const refSeq: string | undefined = refData.getSequence( + Number((item.min as unknown as number) + 1), Number(item.max), ) seqData += item.strand === -1 && refSeq ? revcom(refSeq) : refSeq @@ -142,7 +142,7 @@ export const TranscriptSequence = observer(function TranscriptSequence({ count != transcriptItems.length ) { // Intron etc. between CDS/UTRs. No need to check this on very last item - const refSeq: string | undefined = refData?.getSequence( + const refSeq: string | undefined = refData.getSequence( lastEnd + 1, Number(item.min) - 1, ) @@ -154,8 +154,8 @@ export const TranscriptSequence = observer(function TranscriptSequence({ item.type === 'three_prime_UTR' || item.type === 'five_prime_UTR' ) { - const refSeq: string | undefined = refData?.getSequence( - Number(item.min + 1), + const refSeq: string | undefined = refData.getSequence( + Number((item.min as unknown as number) + 1), Number(item.max), ) seqData += item.strand === -1 && refSeq ? revcom(refSeq) : refSeq @@ -185,7 +185,7 @@ export const TranscriptSequence = observer(function TranscriptSequence({ } } - async function handleChangeSeqOption(e: SelectChangeEvent) { + function handleChangeSeqOption(e: SelectChangeEvent) { const option = e.target.value setSelectedOption(option) getSequenceAsTextSegment(option) @@ -201,7 +201,7 @@ export const TranscriptSequence = observer(function TranscriptSequence({ .then(() => { // console.log('Text copied to clipboard!') }) - .catch((error_) => { + .catch((error_: unknown) => { console.error('Failed to copy text to clipboard', error_) }) } diff --git a/packages/jbrowse-plugin-apollo/src/FeatureDetailsWidget/model.ts b/packages/jbrowse-plugin-apollo/src/FeatureDetailsWidget/model.ts index 75117cc96..a9ff3afc6 100644 --- a/packages/jbrowse-plugin-apollo/src/FeatureDetailsWidget/model.ts +++ b/packages/jbrowse-plugin-apollo/src/FeatureDetailsWidget/model.ts @@ -72,7 +72,7 @@ export interface ApolloFeatureDetailsWidget export interface ApolloFeatureDetailsWidgetSnapshot extends SnapshotIn {} -export const ApolloTranscriptDetails = types +export const ApolloTranscriptDetailsModel = types .model('ApolloTranscriptDetails', { id: ElementId, type: types.literal('ApolloTranscriptDetails'), @@ -123,3 +123,12 @@ export const ApolloTranscriptDetails = types ) }, })) + +// eslint disables because of +// https://mobx-state-tree.js.org/tips/typescript#using-a-mst-type-at-design-time +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface ApolloTranscriptDetailsWidget + extends Instance {} +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface ApolloTranscriptDetailsWidgetSnapshot + extends SnapshotIn {} diff --git a/packages/jbrowse-plugin-apollo/src/TabularEditor/HybridGrid/featureContextMenuItems.ts b/packages/jbrowse-plugin-apollo/src/TabularEditor/HybridGrid/featureContextMenuItems.ts index 234d65aeb..061bde146 100644 --- a/packages/jbrowse-plugin-apollo/src/TabularEditor/HybridGrid/featureContextMenuItems.ts +++ b/packages/jbrowse-plugin-apollo/src/TabularEditor/HybridGrid/featureContextMenuItems.ts @@ -1,6 +1,10 @@ import { AnnotationFeature } from '@apollo-annotation/mst' import { MenuItem } from '@jbrowse/core/ui' -import { AbstractSessionModel, SessionWithWidgets } from '@jbrowse/core/util' +import { + AbstractSessionModel, + SessionWithWidgets, + isSessionModelWithWidgets, +} from '@jbrowse/core/util' import { ChangeManager } from '../../ChangeManager' import { @@ -133,25 +137,21 @@ export function featureContextMenuItems( }, }, ) - if (feature.type === 'mRNA') { + if (feature.type === 'mRNA' && isSessionModelWithWidgets(session)) { menuItems.push({ label: 'Edit transcript details', onClick: () => { - const ses = session as unknown as AbstractSessionModel - if (ses) { - const sesWidged = session as unknown as SessionWithWidgets - const apolloTranscriptWidget = sesWidged.addWidget( - 'ApolloTranscriptDetails', - 'apolloTranscriptDetails', - { - feature, - assembly: currentAssemblyId, - changeManager, - refName: region.refName, - }, - ) - ses.showWidget?.(apolloTranscriptWidget) - } + const apolloTranscriptWidget = session.addWidget( + 'ApolloTranscriptDetails', + 'apolloTranscriptDetails', + { + feature, + assembly: currentAssemblyId, + changeManager, + refName: region.refName, + }, + ) + session.showWidget(apolloTranscriptWidget) }, }) }