jbrowse-plugin-msaview 2.4.2 → 2.4.3

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 (71) hide show
  1. package/dist/LaunchMsaView/components/LaunchMsaViewDialog.js +3 -4
  2. package/dist/LaunchMsaView/components/LaunchMsaViewDialog.js.map +1 -1
  3. package/dist/LaunchMsaView/components/LaunchPanelContent.d.ts +5 -0
  4. package/dist/LaunchMsaView/components/LaunchPanelContent.js +16 -0
  5. package/dist/LaunchMsaView/components/LaunchPanelContent.js.map +1 -0
  6. package/dist/LaunchMsaView/components/ManualMSALoader/ManualMSALoader.js +22 -25
  7. package/dist/LaunchMsaView/components/ManualMSALoader/ManualMSALoader.js.map +1 -1
  8. package/dist/LaunchMsaView/components/NCBIBlastQuery/CachedBlastResults.js +12 -24
  9. package/dist/LaunchMsaView/components/NCBIBlastQuery/CachedBlastResults.js.map +1 -1
  10. package/dist/LaunchMsaView/components/NCBIBlastQuery/MsaAlgorithmSelect.d.ts +7 -0
  11. package/dist/LaunchMsaView/components/NCBIBlastQuery/MsaAlgorithmSelect.js +10 -0
  12. package/dist/LaunchMsaView/components/NCBIBlastQuery/MsaAlgorithmSelect.js.map +1 -0
  13. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastAutomaticPanel.js +23 -32
  14. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastAutomaticPanel.js.map +1 -1
  15. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastManualPanel.js +9 -15
  16. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastManualPanel.js.map +1 -1
  17. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastMethodSelector.d.ts +3 -2
  18. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastMethodSelector.js.map +1 -1
  19. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastPanel.d.ts +25 -0
  20. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastPanel.js.map +1 -1
  21. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastRIDPanel.js +22 -32
  22. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastRIDPanel.js.map +1 -1
  23. package/dist/LaunchMsaView/components/NCBIBlastQuery/useCachedBlastResults.js +2 -9
  24. package/dist/LaunchMsaView/components/NCBIBlastQuery/useCachedBlastResults.js.map +1 -1
  25. package/dist/LaunchMsaView/components/PreLoadedMSA/PreLoadedMSADataPanel.js +30 -29
  26. package/dist/LaunchMsaView/components/PreLoadedMSA/PreLoadedMSADataPanel.js.map +1 -1
  27. package/dist/LaunchMsaView/components/PreLoadedMSA/fetchMSAData.js +8 -6
  28. package/dist/LaunchMsaView/components/PreLoadedMSA/fetchMSAData.js.map +1 -1
  29. package/dist/LaunchMsaView/components/SubmitCancelActions.d.ts +8 -0
  30. package/dist/LaunchMsaView/components/SubmitCancelActions.js +12 -0
  31. package/dist/LaunchMsaView/components/SubmitCancelActions.js.map +1 -0
  32. package/dist/LaunchMsaView/components/TranscriptSelector.d.ts +2 -2
  33. package/dist/LaunchMsaView/components/TranscriptSelector.js +2 -2
  34. package/dist/LaunchMsaView/components/TranscriptSelector.js.map +1 -1
  35. package/dist/LaunchMsaView/components/useSWRFeatureSequence.js +3 -13
  36. package/dist/LaunchMsaView/components/useSWRFeatureSequence.js.map +1 -1
  37. package/dist/LaunchMsaView/components/useTranscriptSelection.js +10 -12
  38. package/dist/LaunchMsaView/components/useTranscriptSelection.js.map +1 -1
  39. package/dist/LaunchMsaView/util.d.ts +4 -1
  40. package/dist/LaunchMsaView/util.js +29 -24
  41. package/dist/LaunchMsaView/util.js.map +1 -1
  42. package/dist/jbrowse-plugin-msaview.umd.production.min.js +24 -24
  43. package/dist/jbrowse-plugin-msaview.umd.production.min.js.map +4 -4
  44. package/dist/{LaunchMsaView/components/PreLoadedMSA/consts.d.ts → utils/swrConfig.d.ts} +1 -1
  45. package/dist/{LaunchMsaView/components/PreLoadedMSA/consts.js → utils/swrConfig.js} +2 -2
  46. package/dist/utils/swrConfig.js.map +1 -0
  47. package/dist/version.d.ts +1 -1
  48. package/dist/version.js +1 -1
  49. package/package.json +1 -1
  50. package/src/LaunchMsaView/components/LaunchMsaViewDialog.tsx +9 -6
  51. package/src/LaunchMsaView/components/LaunchPanelContent.tsx +27 -0
  52. package/src/LaunchMsaView/components/ManualMSALoader/ManualMSALoader.tsx +28 -60
  53. package/src/LaunchMsaView/components/NCBIBlastQuery/CachedBlastResults.tsx +21 -33
  54. package/src/LaunchMsaView/components/NCBIBlastQuery/MsaAlgorithmSelect.tsx +37 -0
  55. package/src/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastAutomaticPanel.tsx +29 -75
  56. package/src/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastManualPanel.tsx +10 -31
  57. package/src/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastMethodSelector.tsx +5 -3
  58. package/src/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastPanel.tsx +5 -2
  59. package/src/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastRIDPanel.tsx +28 -78
  60. package/src/LaunchMsaView/components/NCBIBlastQuery/useCachedBlastResults.ts +2 -10
  61. package/src/LaunchMsaView/components/PreLoadedMSA/PreLoadedMSADataPanel.tsx +34 -57
  62. package/src/LaunchMsaView/components/PreLoadedMSA/fetchMSAData.ts +17 -8
  63. package/src/LaunchMsaView/components/SubmitCancelActions.tsx +41 -0
  64. package/src/LaunchMsaView/components/TranscriptSelector.tsx +3 -3
  65. package/src/LaunchMsaView/components/useSWRFeatureSequence.ts +6 -15
  66. package/src/LaunchMsaView/components/useTranscriptSelection.ts +13 -15
  67. package/src/LaunchMsaView/util.ts +35 -25
  68. package/src/MsaViewPanel/util.ts +3 -3
  69. package/src/{LaunchMsaView/components/PreLoadedMSA/consts.ts → utils/swrConfig.ts} +1 -1
  70. package/src/version.ts +1 -1
  71. package/dist/LaunchMsaView/components/PreLoadedMSA/consts.js.map +0 -1
@@ -1,4 +1,4 @@
1
- export declare const swrFlags: {
1
+ export declare const staticSwrConfig: {
2
2
  revalidateOnFocus: boolean;
3
3
  revalidateOnReconnect: boolean;
4
4
  revalidateIfStale: boolean;
@@ -1,4 +1,4 @@
1
- export const swrFlags = {
1
+ export const staticSwrConfig = {
2
2
  revalidateOnFocus: false,
3
3
  revalidateOnReconnect: false,
4
4
  revalidateIfStale: false,
@@ -6,4 +6,4 @@ export const swrFlags = {
6
6
  refreshWhenOffline: false,
7
7
  shouldRetryOnError: false,
8
8
  };
9
- //# sourceMappingURL=consts.js.map
9
+ //# sourceMappingURL=swrConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swrConfig.js","sourceRoot":"","sources":["../../src/utils/swrConfig.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,iBAAiB,EAAE,KAAK;IACxB,qBAAqB,EAAE,KAAK;IAC5B,iBAAiB,EAAE,KAAK;IACxB,iBAAiB,EAAE,KAAK;IACxB,kBAAkB,EAAE,KAAK;IACzB,kBAAkB,EAAE,KAAK;CAC1B,CAAA"}
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "2.4.2";
1
+ export declare const version = "2.4.3";
package/dist/version.js CHANGED
@@ -1,2 +1,2 @@
1
- export const version = '2.4.2';
1
+ export const version = '2.4.3';
2
2
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.4.2",
2
+ "version": "2.4.3",
3
3
  "license": "MIT",
4
4
  "name": "jbrowse-plugin-msaview",
5
5
  "repository": {
@@ -25,15 +25,18 @@ export default function LaunchMsaViewDialog({
25
25
  const datasets = readMsaDatasets(session.jbrowse)
26
26
  const hasPreloadedDatasets = !!datasets?.length
27
27
 
28
- const [value, setValue] = useState('ncbi_blast')
29
-
30
- const handleChange = (_event: React.SyntheticEvent, newValue: string) => {
31
- setValue(newValue)
32
- }
28
+ const [value, setValue] = useState<
29
+ 'ncbi_blast' | 'preloaded_msa' | 'manual_msa'
30
+ >('ncbi_blast')
33
31
 
34
32
  return (
35
33
  <Dialog maxWidth="xl" title="Launch MSA view" open onClose={handleClose}>
36
- <Tabs value={value} onChange={handleChange}>
34
+ <Tabs
35
+ value={value}
36
+ onChange={(_event, newValue) => {
37
+ setValue(newValue)
38
+ }}
39
+ >
37
40
  <Tab label="NCBI BLAST query" value="ncbi_blast" />
38
41
  {hasPreloadedDatasets ? (
39
42
  <Tab label="Pre-loaded MSA datasets" value="preloaded_msa" />
@@ -0,0 +1,27 @@
1
+ import React from 'react'
2
+
3
+ import { ErrorMessage } from '@jbrowse/core/ui'
4
+ import { DialogContent } from '@mui/material'
5
+ import { makeStyles } from 'tss-react/mui'
6
+
7
+ const useStyles = makeStyles()({
8
+ dialogContent: {
9
+ width: '80em',
10
+ },
11
+ })
12
+
13
+ export default function LaunchPanelContent({
14
+ error,
15
+ children,
16
+ }: {
17
+ error?: unknown
18
+ children: React.ReactNode
19
+ }) {
20
+ const { classes } = useStyles()
21
+ return (
22
+ <DialogContent className={classes.dialogContent}>
23
+ {error ? <ErrorMessage error={error} /> : null}
24
+ {children}
25
+ </DialogContent>
26
+ )
27
+ }
@@ -1,12 +1,9 @@
1
1
  import React, { useState } from 'react'
2
2
 
3
- import { ErrorMessage, FileSelector } from '@jbrowse/core/ui'
4
- import { getContainingView, getSession } from '@jbrowse/core/util'
3
+ import { FileSelector } from '@jbrowse/core/ui'
4
+ import { getSession } from '@jbrowse/core/util'
5
5
  import {
6
6
  Alert,
7
- Button,
8
- DialogActions,
9
- DialogContent,
10
7
  FormControl,
11
8
  FormControlLabel,
12
9
  Radio,
@@ -17,7 +14,9 @@ import { makeStyles } from 'tss-react/mui'
17
14
 
18
15
  import { launchView } from './launchView'
19
16
  import TextField2 from '../../../components/TextField2'
20
- import { getGeneDisplayName } from '../../util'
17
+ import { getGeneDisplayName, getLinearGenomeView } from '../../util'
18
+ import LaunchPanelContent from '../LaunchPanelContent'
19
+ import SubmitCancelActions from '../SubmitCancelActions'
21
20
  import TranscriptSelector from '../TranscriptSelector'
22
21
  import { useTranscriptSelection } from '../useTranscriptSelection'
23
22
 
@@ -26,12 +25,8 @@ import type {
26
25
  Feature,
27
26
  FileLocation,
28
27
  } from '@jbrowse/core/util'
29
- import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
30
28
 
31
29
  const useStyles = makeStyles()({
32
- dialogContent: {
33
- width: '80em',
34
- },
35
30
  textAreaFont: {
36
31
  fontFamily: 'Courier New',
37
32
  },
@@ -62,7 +57,7 @@ const ManualMSALoader = observer(function PreLoadedMSA2({
62
57
  handleClose: () => void
63
58
  }) {
64
59
  const session = getSession(model)
65
- const view = getContainingView(model) as LinearGenomeViewModel
60
+ const view = getLinearGenomeView(model)
66
61
  const { classes } = useStyles()
67
62
  const [launchViewError, setLaunchViewError] = useState<unknown>()
68
63
  const [inputMethod, setInputMethod] = useState<'file' | 'text'>('file')
@@ -71,20 +66,13 @@ const ManualMSALoader = observer(function PreLoadedMSA2({
71
66
  const [msaFileLocation, setMsaFileLocation] = useState<FileLocation>()
72
67
  const [treeFileLocation, setTreeFileLocation] = useState<FileLocation>()
73
68
  const [querySeqName, setQuerySeqName] = useState('')
74
- const {
75
- options,
76
- selectedId,
77
- setSelectedId,
78
- selectedTranscript,
79
- proteinSequence,
80
- error,
81
- } = useTranscriptSelection({ feature, view })
69
+ const transcriptSelection = useTranscriptSelection({ feature, view })
70
+ const { selectedTranscript, error } = transcriptSelection
82
71
 
83
72
  const e = launchViewError ?? error
84
73
  return (
85
74
  <>
86
- <DialogContent className={classes.dialogContent}>
87
- {e ? <ErrorMessage error={e} /> : null}
75
+ <LaunchPanelContent error={e}>
88
76
  <FormControl component="fieldset">
89
77
  <RadioGroup
90
78
  row
@@ -155,14 +143,7 @@ const ManualMSALoader = observer(function PreLoadedMSA2({
155
143
  )}
156
144
  </div>
157
145
 
158
- <TranscriptSelector
159
- feature={feature}
160
- options={options}
161
- selectedId={selectedId}
162
- selectedTranscript={selectedTranscript}
163
- onTranscriptChange={setSelectedId}
164
- proteinSequence={proteinSequence}
165
- />
146
+ <TranscriptSelector feature={feature} {...transcriptSelection} />
166
147
 
167
148
  <TextField2
168
149
  variant="outlined"
@@ -185,25 +166,23 @@ const ManualMSALoader = observer(function PreLoadedMSA2({
185
166
  highlights will not work.
186
167
  </Alert>
187
168
  ) : null}
188
- </DialogContent>
169
+ </LaunchPanelContent>
189
170
 
190
- <DialogActions>
191
- <Button
192
- color="primary"
193
- variant="contained"
194
- disabled={
195
- !selectedTranscript ||
196
- (inputMethod === 'file' && !msaFileLocation) ||
197
- (inputMethod === 'text' && !msaText.trim())
198
- }
199
- onClick={() => {
200
- try {
171
+ <SubmitCancelActions
172
+ submitDisabled={
173
+ !selectedTranscript ||
174
+ (inputMethod === 'file' && !msaFileLocation) ||
175
+ (inputMethod === 'text' && !msaText.trim())
176
+ }
177
+ onSubmit={() => {
178
+ try {
179
+ if (selectedTranscript) {
201
180
  setLaunchViewError(undefined)
202
181
  launchView({
203
182
  session,
204
183
  newViewTitle: getGeneDisplayName(selectedTranscript),
205
184
  view,
206
- feature: selectedTranscript!,
185
+ feature: selectedTranscript,
207
186
  querySeqName: querySeqName.trim(),
208
187
  ...(inputMethod === 'file'
209
188
  ? {
@@ -217,26 +196,15 @@ const ManualMSALoader = observer(function PreLoadedMSA2({
217
196
  },
218
197
  }),
219
198
  })
220
-
221
199
  handleClose()
222
- } catch (err) {
223
- console.error(err)
224
- setLaunchViewError(err)
225
200
  }
226
- }}
227
- >
228
- Submit
229
- </Button>
230
- <Button
231
- color="secondary"
232
- variant="contained"
233
- onClick={() => {
234
- handleClose()
235
- }}
236
- >
237
- Cancel
238
- </Button>
239
- </DialogActions>
201
+ } catch (err) {
202
+ console.error(err)
203
+ setLaunchViewError(err)
204
+ }
205
+ }}
206
+ onCancel={handleClose}
207
+ />
240
208
  </>
241
209
  )
242
210
  })
@@ -1,7 +1,6 @@
1
1
  import React, { useMemo, useState } from 'react'
2
2
 
3
3
  import { ErrorMessage } from '@jbrowse/core/ui'
4
- import { getContainingView } from '@jbrowse/core/util'
5
4
  import DeleteIcon from '@mui/icons-material/Delete'
6
5
  import {
7
6
  Button,
@@ -17,11 +16,10 @@ import { makeStyles } from 'tss-react/mui'
17
16
 
18
17
  import { blastLaunchViewFromCache } from './blastLaunchView'
19
18
  import { useCachedBlastResults } from './useCachedBlastResults'
20
- import { getGeneIdentifiers } from '../../util'
19
+ import { getGeneIdentifiers, getLinearGenomeView } from '../../util'
21
20
 
22
21
  import type { CachedBlastResult } from '../../../utils/blastCache'
23
22
  import type { AbstractTrackModel, Feature } from '@jbrowse/core/util'
24
- import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
25
23
 
26
24
  const useStyles = makeStyles()({
27
25
  header: {
@@ -37,17 +35,15 @@ const useStyles = makeStyles()({
37
35
  })
38
36
 
39
37
  function getResultDisplayName(result: CachedBlastResult): string {
40
- const parts = []
41
- if (result.geneName) {
42
- parts.push(result.geneName)
43
- }
44
- if (result.transcriptName && result.transcriptName !== result.geneName) {
45
- parts.push(result.transcriptName)
46
- }
47
- if (parts.length === 0) {
48
- parts.push(result.geneId ?? result.transcriptId ?? 'Unknown')
49
- }
50
- return parts.join(' - ')
38
+ const parts = [
39
+ result.geneName,
40
+ result.transcriptName !== result.geneName
41
+ ? result.transcriptName
42
+ : undefined,
43
+ ].filter((p): p is string => !!p)
44
+ return parts.length > 0
45
+ ? parts.join(' - ')
46
+ : (result.geneId ?? result.transcriptId ?? 'Unknown')
51
47
  }
52
48
 
53
49
  const CachedBlastResults = observer(function ({
@@ -60,7 +56,7 @@ const CachedBlastResults = observer(function ({
60
56
  feature: Feature
61
57
  }) {
62
58
  const { classes } = useStyles()
63
- const view = getContainingView(model) as LinearGenomeViewModel
59
+ const view = getLinearGenomeView(model)
64
60
  const [operationError, setOperationError] = useState<unknown>()
65
61
 
66
62
  const geneIds = useMemo(() => getGeneIdentifiers(feature), [feature])
@@ -78,24 +74,16 @@ const CachedBlastResults = observer(function ({
78
74
  }
79
75
 
80
76
  const displayError = error ?? operationError
81
- if (displayError) {
82
- return <ErrorMessage error={displayError} />
83
- }
84
-
85
- if (isLoading) {
86
- return <Typography>Loading cached results...</Typography>
87
- }
88
-
89
- if (results.length === 0) {
90
- return (
91
- <Typography color="textSecondary">
92
- No cached BLAST results found for this gene. Run a BLAST query to cache
93
- results.
94
- </Typography>
95
- )
96
- }
97
-
98
- return (
77
+ return displayError ? (
78
+ <ErrorMessage error={displayError} />
79
+ ) : isLoading ? (
80
+ <Typography>Loading cached results...</Typography>
81
+ ) : results.length === 0 ? (
82
+ <Typography color="textSecondary">
83
+ No cached BLAST results found for this gene. Run a BLAST query to cache
84
+ results.
85
+ </Typography>
86
+ ) : (
99
87
  <div>
100
88
  <div className={classes.header}>
101
89
  <Typography variant="subtitle1">
@@ -0,0 +1,37 @@
1
+ import React from 'react'
2
+
3
+ import { MenuItem } from '@mui/material'
4
+
5
+ import { msaAlgorithms } from './consts'
6
+ import TextField2 from '../../../components/TextField2'
7
+
8
+ import type { MsaAlgorithm } from './consts'
9
+
10
+ export default function MsaAlgorithmSelect({
11
+ value,
12
+ onChange,
13
+ className,
14
+ }: {
15
+ value: MsaAlgorithm
16
+ onChange: (val: MsaAlgorithm) => void
17
+ className?: string
18
+ }) {
19
+ return (
20
+ <TextField2
21
+ variant="outlined"
22
+ label="MSA Algorithm"
23
+ className={className}
24
+ select
25
+ value={value}
26
+ onChange={event => {
27
+ onChange(event.target.value as MsaAlgorithm)
28
+ }}
29
+ >
30
+ {msaAlgorithms.map(val => (
31
+ <MenuItem value={val} key={val}>
32
+ {val}
33
+ </MenuItem>
34
+ ))}
35
+ </TextField2>
36
+ )
37
+ }
@@ -1,15 +1,10 @@
1
1
  import React, { useMemo, useState } from 'react'
2
2
 
3
- import { ErrorMessage } from '@jbrowse/core/ui'
4
- import { getContainingView } from '@jbrowse/core/util'
5
3
  import ExpandMoreIcon from '@mui/icons-material/ExpandMore'
6
4
  import {
7
5
  Accordion,
8
6
  AccordionDetails,
9
7
  AccordionSummary,
10
- Button,
11
- DialogActions,
12
- DialogContent,
13
8
  MenuItem,
14
9
  Typography,
15
10
  } from '@mui/material'
@@ -17,26 +12,25 @@ import { observer } from 'mobx-react'
17
12
  import { makeStyles } from 'tss-react/mui'
18
13
 
19
14
  import CachedBlastResults from './CachedBlastResults'
15
+ import MsaAlgorithmSelect from './MsaAlgorithmSelect'
20
16
  import { blastLaunchView } from './blastLaunchView'
21
- import { blastDatabaseOptions, blastPrograms, msaAlgorithms } from './consts'
17
+ import { blastDatabaseOptions, blastPrograms } from './consts'
22
18
  import { useCachedBlastResults } from './useCachedBlastResults'
23
19
  import TextField2 from '../../../components/TextField2'
24
20
  import {
25
- getGeneDisplayName,
21
+ getBlastViewTitle,
26
22
  getGeneIdentifiers,
27
- getTranscriptDisplayName,
23
+ getLinearGenomeView,
28
24
  } from '../../util'
25
+ import LaunchPanelContent from '../LaunchPanelContent'
26
+ import SubmitCancelActions from '../SubmitCancelActions'
29
27
  import TranscriptSelector from '../TranscriptSelector'
30
28
  import { useTranscriptSelection } from '../useTranscriptSelection'
31
29
 
32
30
  import type { BlastDatabase, BlastProgram, MsaAlgorithm } from './consts'
33
31
  import type { AbstractTrackModel, Feature } from '@jbrowse/core/util'
34
- import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
35
32
 
36
33
  const useStyles = makeStyles()({
37
- dialogContent: {
38
- width: '80em',
39
- },
40
34
  selectField: {
41
35
  width: 150,
42
36
  },
@@ -69,7 +63,7 @@ const NCBIBlastAutomaticPanel = observer(function ({
69
63
  children: React.ReactNode
70
64
  }) {
71
65
  const { classes } = useStyles()
72
- const view = getContainingView(model) as LinearGenomeViewModel
66
+ const view = getLinearGenomeView(model)
73
67
  const [launchViewError, setLaunchViewError] = useState<unknown>()
74
68
  const [selectedBlastDatabase, setSelectedBlastDatabase] =
75
69
  useState<BlastDatabase>('nr')
@@ -82,20 +76,13 @@ const NCBIBlastAutomaticPanel = observer(function ({
82
76
  const { results: cachedResults, error: cachedResultsError } =
83
77
  useCachedBlastResults(geneIds)
84
78
 
85
- const {
86
- options,
87
- selectedId,
88
- setSelectedId,
89
- selectedTranscript,
90
- proteinSequence,
91
- error: proteinSequenceError,
92
- } = useTranscriptSelection({ feature, view })
93
- const e = proteinSequenceError ?? launchViewError ?? cachedResultsError
79
+ const transcriptSelection = useTranscriptSelection({ feature, view })
80
+ const { selectedTranscript, proteinSequence } = transcriptSelection
81
+ const e = transcriptSelection.error ?? launchViewError ?? cachedResultsError
94
82
  return (
95
83
  <>
96
- <DialogContent className={classes.dialogContent}>
84
+ <LaunchPanelContent error={e}>
97
85
  {children}
98
- {e ? <ErrorMessage error={e} /> : null}
99
86
  <TextField2
100
87
  variant="outlined"
101
88
  label="BLAST database"
@@ -117,22 +104,11 @@ const NCBIBlastAutomaticPanel = observer(function ({
117
104
  ))}
118
105
  </TextField2>
119
106
 
120
- <TextField2
121
- variant="outlined"
122
- label="MSA Algorithm"
107
+ <MsaAlgorithmSelect
123
108
  className={classes.selectField}
124
- select
125
109
  value={selectedMsaAlgorithm}
126
- onChange={event => {
127
- setSelectedMsaAlgorithm(event.target.value as MsaAlgorithm)
128
- }}
129
- >
130
- {msaAlgorithms.map(val => (
131
- <MenuItem value={val} key={val}>
132
- {val}
133
- </MenuItem>
134
- ))}
135
- </TextField2>
110
+ onChange={setSelectedMsaAlgorithm}
111
+ />
136
112
 
137
113
  <div className={classes.databaseFieldContainer}>
138
114
  <TextField2
@@ -162,14 +138,7 @@ const NCBIBlastAutomaticPanel = observer(function ({
162
138
  ) : null}
163
139
  </div>
164
140
 
165
- <TranscriptSelector
166
- feature={feature}
167
- options={options}
168
- selectedId={selectedId}
169
- selectedTranscript={selectedTranscript}
170
- onTranscriptChange={setSelectedId}
171
- proteinSequence={proteinSequence}
172
- />
141
+ <TranscriptSelector feature={feature} {...transcriptSelection} />
173
142
 
174
143
  <Typography className={classes.infoText}>
175
144
  This panel will automatically submit a query to NCBI. Using blastp can
@@ -196,21 +165,17 @@ const NCBIBlastAutomaticPanel = observer(function ({
196
165
  </AccordionDetails>
197
166
  </Accordion>
198
167
  ) : null}
199
- </DialogContent>
200
- <DialogActions>
201
- <Button
202
- color="primary"
203
- variant="contained"
204
- onClick={() => {
205
- try {
206
- if (!selectedTranscript) {
207
- return
208
- }
168
+ </LaunchPanelContent>
169
+ <SubmitCancelActions
170
+ submitDisabled={!proteinSequence}
171
+ onSubmit={() => {
172
+ try {
173
+ if (selectedTranscript) {
209
174
  setLaunchViewError(undefined)
210
175
  blastLaunchView({
211
176
  feature: selectedTranscript,
212
177
  view,
213
- newViewTitle: `BLAST - ${getGeneDisplayName(feature)} - ${getTranscriptDisplayName(selectedTranscript)}`,
178
+ newViewTitle: getBlastViewTitle(feature, selectedTranscript),
214
179
  blastParams: {
215
180
  baseUrl,
216
181
  blastProgram: selectedBlastProgram,
@@ -221,25 +186,14 @@ const NCBIBlastAutomaticPanel = observer(function ({
221
186
  },
222
187
  })
223
188
  handleClose()
224
- } catch (e) {
225
- console.error(e)
226
- setLaunchViewError(e)
227
189
  }
228
- }}
229
- disabled={!proteinSequence}
230
- >
231
- Submit
232
- </Button>
233
- <Button
234
- color="secondary"
235
- variant="contained"
236
- onClick={() => {
237
- handleClose()
238
- }}
239
- >
240
- Cancel
241
- </Button>
242
- </DialogActions>
190
+ } catch (e) {
191
+ console.error(e)
192
+ setLaunchViewError(e)
193
+ }
194
+ }}
195
+ onCancel={handleClose}
196
+ />
243
197
  </>
244
198
  )
245
199
  })
@@ -1,26 +1,19 @@
1
1
  import React from 'react'
2
2
 
3
- import { ErrorMessage } from '@jbrowse/core/ui'
4
- import { getContainingView, shorten2 } from '@jbrowse/core/util'
5
- import { Button, DialogActions, DialogContent, Typography } from '@mui/material'
3
+ import { shorten2 } from '@jbrowse/core/util'
4
+ import { Button, DialogActions, Typography } from '@mui/material'
6
5
  import { observer } from 'mobx-react'
7
6
  import { makeStyles } from 'tss-react/mui'
8
7
 
9
8
  import ExternalLink from '../../../components/ExternalLink'
10
- import { cleanProteinSequence } from '../../util'
9
+ import { cleanProteinSequence, getLinearGenomeView } from '../../util'
10
+ import LaunchPanelContent from '../LaunchPanelContent'
11
11
  import TranscriptSelector from '../TranscriptSelector'
12
12
  import { useTranscriptSelection } from '../useTranscriptSelection'
13
13
 
14
14
  import type { AbstractTrackModel, Feature } from '@jbrowse/core/util'
15
- import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
16
15
 
17
16
  const useStyles = makeStyles()({
18
- dialogContent: {
19
- width: '80em',
20
- },
21
- textAreaFont: {
22
- fontFamily: 'Courier New',
23
- },
24
17
  ncbiLink: {
25
18
  wordBreak: 'break-all',
26
19
  margin: 30,
@@ -45,15 +38,9 @@ const NCBIBlastManualPanel = observer(function ({
45
38
  handleClose: () => void
46
39
  }) {
47
40
  const { classes } = useStyles()
48
- const view = getContainingView(model) as LinearGenomeViewModel
49
- const {
50
- options,
51
- selectedId,
52
- setSelectedId,
53
- selectedTranscript,
54
- proteinSequence,
55
- error,
56
- } = useTranscriptSelection({ feature, view })
41
+ const view = getLinearGenomeView(model)
42
+ const transcriptSelection = useTranscriptSelection({ feature, view })
43
+ const { proteinSequence, error } = transcriptSelection
57
44
 
58
45
  const s2 = cleanProteinSequence(proteinSequence)
59
46
  const link = `${baseUrl}?PAGE_TYPE=BlastSearch&PAGE=Proteins&PROGRAM=blastp&QUERY=${s2}`
@@ -61,18 +48,10 @@ const NCBIBlastManualPanel = observer(function ({
61
48
 
62
49
  return (
63
50
  <>
64
- <DialogContent className={classes.dialogContent}>
51
+ <LaunchPanelContent error={error}>
65
52
  {children}
66
- {error ? <ErrorMessage error={error} /> : null}
67
53
 
68
- <TranscriptSelector
69
- feature={feature}
70
- options={options}
71
- selectedId={selectedId}
72
- selectedTranscript={selectedTranscript}
73
- onTranscriptChange={setSelectedId}
74
- proteinSequence={proteinSequence}
75
- />
54
+ <TranscriptSelector feature={feature} {...transcriptSelection} />
76
55
 
77
56
  {proteinSequence ? (
78
57
  <div className={classes.ncbiLink}>
@@ -87,7 +66,7 @@ const NCBIBlastManualPanel = observer(function ({
87
66
  completes, you can download an MSA (.aln file) and optionally a Newick
88
67
  tree (.nh) and paste the results into JBrowse
89
68
  </Typography>
90
- </DialogContent>
69
+ </LaunchPanelContent>
91
70
 
92
71
  <DialogActions>
93
72
  <Button
@@ -2,12 +2,14 @@ import React from 'react'
2
2
 
3
3
  import { FormControl, FormControlLabel, Radio, RadioGroup } from '@mui/material'
4
4
 
5
+ import type { BlastLookupMethod } from './NCBIBlastPanel'
6
+
5
7
  export default function NCBIBlastMethodSelector({
6
8
  lookupMethod,
7
9
  setLookupMethod,
8
10
  }: {
9
- lookupMethod: string
10
- setLookupMethod: (method: string) => void
11
+ lookupMethod: BlastLookupMethod
12
+ setLookupMethod: (method: BlastLookupMethod) => void
11
13
  }) {
12
14
  return (
13
15
  <FormControl component="fieldset">
@@ -15,7 +17,7 @@ export default function NCBIBlastMethodSelector({
15
17
  row
16
18
  value={lookupMethod}
17
19
  onChange={event => {
18
- setLookupMethod(event.target.value)
20
+ setLookupMethod(event.target.value as BlastLookupMethod)
19
21
  }}
20
22
  >
21
23
  <FormControlLabel