jbrowse-plugin-msaview 2.3.3 → 2.3.8

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 (76) hide show
  1. package/README.md +15 -216
  2. package/dist/AddHighlightModel/GenomeMouseoverHighlight.js.map +1 -1
  3. package/dist/BgzipFastaMsaAdapter/BgzipFastaMsaAdapter.js +2 -11
  4. package/dist/BgzipFastaMsaAdapter/BgzipFastaMsaAdapter.js.map +1 -1
  5. package/dist/LaunchMsaView/components/ManualMSALoader/ManualMSALoader.js +19 -4
  6. package/dist/LaunchMsaView/components/ManualMSALoader/ManualMSALoader.js.map +1 -1
  7. package/dist/LaunchMsaView/components/NCBIBlastQuery/CachedBlastResults.js +39 -53
  8. package/dist/LaunchMsaView/components/NCBIBlastQuery/CachedBlastResults.js.map +1 -1
  9. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastAutomaticPanel.js +9 -22
  10. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastAutomaticPanel.js.map +1 -1
  11. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastManualPanel.js +4 -1
  12. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastManualPanel.js.map +1 -1
  13. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastPanel.js +8 -1
  14. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastPanel.js.map +1 -1
  15. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastRIDPanel.js +15 -7
  16. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastRIDPanel.js.map +1 -1
  17. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBISettingsDialog.js +8 -1
  18. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBISettingsDialog.js.map +1 -1
  19. package/dist/LaunchMsaView/components/NCBIBlastQuery/useCachedBlastResults.d.ts +7 -0
  20. package/dist/LaunchMsaView/components/NCBIBlastQuery/useCachedBlastResults.js +32 -0
  21. package/dist/LaunchMsaView/components/NCBIBlastQuery/useCachedBlastResults.js.map +1 -0
  22. package/dist/LaunchMsaView/components/PreLoadedMSA/PreLoadedMSADataPanel.js +7 -2
  23. package/dist/LaunchMsaView/components/PreLoadedMSA/PreLoadedMSADataPanel.js.map +1 -1
  24. package/dist/LaunchMsaView/components/TabPanel.js +1 -1
  25. package/dist/LaunchMsaView/components/TabPanel.js.map +1 -1
  26. package/dist/LaunchMsaView/components/TranscriptSelector.js +7 -3
  27. package/dist/LaunchMsaView/components/TranscriptSelector.js.map +1 -1
  28. package/dist/LaunchMsaView/components/useTranscriptSelection.js +15 -14
  29. package/dist/LaunchMsaView/components/useTranscriptSelection.js.map +1 -1
  30. package/dist/MsaViewPanel/afterCreateAutoruns.js +17 -18
  31. package/dist/MsaViewPanel/afterCreateAutoruns.js.map +1 -1
  32. package/dist/MsaViewPanel/components/ConnectStructureDialog.js +15 -10
  33. package/dist/MsaViewPanel/components/ConnectStructureDialog.js.map +1 -1
  34. package/dist/MsaViewPanel/components/ErrorBoundary.d.ts +19 -0
  35. package/dist/MsaViewPanel/components/ErrorBoundary.js +22 -0
  36. package/dist/MsaViewPanel/components/ErrorBoundary.js.map +1 -0
  37. package/dist/MsaViewPanel/components/MsaViewPanel.js +11 -2
  38. package/dist/MsaViewPanel/components/MsaViewPanel.js.map +1 -1
  39. package/dist/MsaViewPanel/model.d.ts +2 -14
  40. package/dist/MsaViewPanel/model.js +13 -10
  41. package/dist/MsaViewPanel/model.js.map +1 -1
  42. package/dist/MsaViewPanel/pairwiseAlignment.js +15 -10
  43. package/dist/MsaViewPanel/pairwiseAlignment.js.map +1 -1
  44. package/dist/MsaViewPanel/structureConnection.d.ts +22 -0
  45. package/dist/MsaViewPanel/structureConnection.js +4 -0
  46. package/dist/MsaViewPanel/structureConnection.js.map +1 -1
  47. package/dist/jbrowse-plugin-msaview.umd.production.min.js +26 -26
  48. package/dist/jbrowse-plugin-msaview.umd.production.min.js.map +4 -4
  49. package/dist/utils/blastCache.js +2 -3
  50. package/dist/utils/blastCache.js.map +1 -1
  51. package/dist/version.d.ts +1 -1
  52. package/dist/version.js +1 -1
  53. package/package.json +33 -35
  54. package/src/AddHighlightModel/GenomeMouseoverHighlight.tsx +1 -2
  55. package/src/BgzipFastaMsaAdapter/BgzipFastaMsaAdapter.ts +2 -11
  56. package/src/LaunchMsaView/components/ManualMSALoader/ManualMSALoader.tsx +22 -7
  57. package/src/LaunchMsaView/components/NCBIBlastQuery/CachedBlastResults.tsx +40 -58
  58. package/src/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastAutomaticPanel.tsx +14 -23
  59. package/src/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastManualPanel.tsx +4 -1
  60. package/src/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastPanel.tsx +9 -1
  61. package/src/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastRIDPanel.tsx +15 -8
  62. package/src/LaunchMsaView/components/NCBIBlastQuery/NCBISettingsDialog.tsx +9 -1
  63. package/src/LaunchMsaView/components/NCBIBlastQuery/useCachedBlastResults.ts +52 -0
  64. package/src/LaunchMsaView/components/PreLoadedMSA/PreLoadedMSADataPanel.tsx +11 -2
  65. package/src/LaunchMsaView/components/TabPanel.tsx +1 -1
  66. package/src/LaunchMsaView/components/TranscriptSelector.tsx +7 -3
  67. package/src/LaunchMsaView/components/useTranscriptSelection.ts +25 -17
  68. package/src/MsaViewPanel/afterCreateAutoruns.ts +17 -18
  69. package/src/MsaViewPanel/components/ConnectStructureDialog.tsx +23 -25
  70. package/src/MsaViewPanel/components/ErrorBoundary.tsx +40 -0
  71. package/src/MsaViewPanel/components/MsaViewPanel.tsx +22 -11
  72. package/src/MsaViewPanel/model.ts +49 -33
  73. package/src/MsaViewPanel/pairwiseAlignment.ts +15 -10
  74. package/src/MsaViewPanel/structureConnection.ts +23 -0
  75. package/src/utils/blastCache.ts +2 -3
  76. package/src/version.ts +1 -1
@@ -15,11 +15,10 @@ async function getDB() {
15
15
  });
16
16
  }
17
17
  function createCacheKey(proteinSequence, blastDatabase, blastProgram, transcriptId) {
18
- const seqKey = proteinSequence.slice(0, 100);
19
18
  if (transcriptId) {
20
- return `${blastDatabase}:${blastProgram}:${transcriptId}:${seqKey}`;
19
+ return `${blastDatabase}:${blastProgram}:${transcriptId}:${proteinSequence}`;
21
20
  }
22
- return `${blastDatabase}:${blastProgram}:${seqKey}`;
21
+ return `${blastDatabase}:${blastProgram}:${proteinSequence}`;
23
22
  }
24
23
  export async function getCachedBlastResult({ proteinSequence, blastDatabase, blastProgram, transcriptId, }) {
25
24
  const db = await getDB();
@@ -1 +1 @@
1
- {"version":3,"file":"blastCache.js","sourceRoot":"","sources":["../../src/utils/blastCache.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"blastCache.js","sourceRoot":"","sources":["../../src/utils/blastCache.ts"],"names":[],"mappings":"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"}
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "2.3.3";
1
+ export declare const version = "2.3.8";
package/dist/version.js CHANGED
@@ -1,2 +1,2 @@
1
- export const version = '2.3.3';
1
+ export const version = '2.3.8';
2
2
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.3.3",
2
+ "version": "2.3.8",
3
3
  "license": "MIT",
4
4
  "name": "jbrowse-plugin-msaview",
5
5
  "repository": {
@@ -15,66 +15,64 @@
15
15
  "dist",
16
16
  "src"
17
17
  ],
18
- "scripts": {
19
- "clean": "rimraf dist",
20
- "start": "node esbuild.mjs --watch",
21
- "format": "prettier --write .",
22
- "build": "tsc && NODE_ENV=production node esbuild.mjs && cp distconfig.json dist/config.json",
23
- "prebuild": "yarn clean",
24
- "lint": "eslint --report-unused-disable-directives --max-warnings 0",
25
- "pretest": "rm -rf .test-jbrowse && npx @jbrowse/cli create .test-jbrowse --nightly",
26
- "test": "vitest run",
27
- "test:watch": "vitest",
28
- "test:setup": "node scripts/test-versions.mjs setup",
29
- "test:setup:version": "node scripts/test-versions.mjs setup",
30
- "test:versions": "node scripts/test-versions.mjs run",
31
- "test:version": "node scripts/test-versions.mjs run",
32
- "prepack": "yarn build",
33
- "preversion": "yarn lint",
34
- "version": "node -e \"console.log('export const version = \\'' + require('./package.json').version + '\\'')\" > src/version.ts && git add src/version.ts",
35
- "postversion": "git push --follow-tags"
36
- },
37
18
  "dependencies": {
38
19
  "@emotion/styled": "^11.14.1",
39
- "g2p_mapper": "^2.0.0",
20
+ "g2p_mapper": "^2.0.1",
40
21
  "idb": "^8.0.3",
41
22
  "pako-esm2": "^2.0.2",
42
- "react-msaview": "^5.0.13",
23
+ "react-msaview": "^5.0.16",
43
24
  "swr": "^2.4.1"
44
25
  },
45
26
  "devDependencies": {
46
27
  "@emotion/react": "^11.14.0",
47
- "@eslint/js": "^9.39.4",
28
+ "@eslint/js": "^10.0.1",
48
29
  "@fal-works/esbuild-plugin-global-externals": "^2.1.2",
49
- "@jbrowse/core": "^4.1.15",
30
+ "@jbrowse/core": "^4.2.0",
50
31
  "@jbrowse/mobx-state-tree": "^5.6.0",
51
- "@jbrowse/plugin-linear-genome-view": "^4.1.15",
32
+ "@jbrowse/plugin-linear-genome-view": "^4.2.0",
52
33
  "@mui/icons-material": "^7.3.10",
53
34
  "@mui/material": "^7.3.10",
54
35
  "@mui/system": "^7.3.10",
55
36
  "@mui/x-data-grid": "^8.28.2",
56
37
  "@types/node": "^25.6.0",
57
38
  "@types/react": "^19.2.14",
39
+ "@typescript-eslint/eslint-plugin": "^8.59.1",
40
+ "@typescript-eslint/parser": "^8.59.1",
58
41
  "esbuild": "^0.28.0",
59
- "eslint": "^9.39.4",
60
- "eslint-plugin-import": "^2.32.0",
42
+ "eslint": "^10.2.1",
43
+ "eslint-plugin-import-x": "^4.16.2",
61
44
  "eslint-plugin-react": "^7.37.5",
62
- "eslint-plugin-react-hooks": "^7.0.1",
63
- "eslint-plugin-react-refresh": "^0.5.2",
45
+ "eslint-plugin-react-hooks": "^7.1.1",
64
46
  "eslint-plugin-unicorn": "^64.0.0",
65
47
  "mobx": "^6.15.0",
66
48
  "mobx-react": "^9.2.1",
67
- "prettier": "^3.8.2",
49
+ "prettier": "^3.8.3",
68
50
  "pretty-bytes": "^7.1.0",
69
- "puppeteer": "^24.40.0",
51
+ "puppeteer": "^24.42.0",
70
52
  "react": "^19.2.5",
71
53
  "react-dom": "^19.2.5",
72
54
  "rimraf": "^6.1.3",
73
55
  "rxjs": "^7.8.2",
74
56
  "serve": "^14.2.6",
75
57
  "tss-react": "^4.9.20",
76
- "typescript": "^6.0.2",
77
- "typescript-eslint": "^8.58.2",
78
- "vitest": "^4.1.4"
58
+ "typescript": "^6.0.3",
59
+ "typescript-eslint": "^8.59.1",
60
+ "vitest": "^4.1.5"
61
+ },
62
+ "scripts": {
63
+ "clean": "rimraf dist",
64
+ "start": "node esbuild.mjs --watch",
65
+ "format": "pnpm prettier --write .",
66
+ "build": "tsc && NODE_ENV=production node esbuild.mjs && cp distconfig.json dist/config.json",
67
+ "prebuild": "pnpm clean",
68
+ "lint": "eslint src --report-unused-disable-directives --max-warnings 0",
69
+ "pretest": "rm -rf .test-jbrowse && npx @jbrowse/cli create .test-jbrowse --nightly",
70
+ "test": "vitest run",
71
+ "test:watch": "vitest",
72
+ "test:setup": "node scripts/test-versions.mjs setup",
73
+ "test:setup:version": "node scripts/test-versions.mjs setup",
74
+ "test:versions": "node scripts/test-versions.mjs run",
75
+ "test:version": "node scripts/test-versions.mjs run",
76
+ "release": "node scripts/release.mjs"
79
77
  }
80
- }
78
+ }
@@ -38,8 +38,7 @@ const GenomeMouseoverHighlightRenderer = observer(function ({
38
38
  hovered,
39
39
  }: {
40
40
  model: LinearGenomeViewModel
41
-
42
- hovered: any
41
+ hovered: object & Record<'hoverPosition', unknown>
43
42
  }) {
44
43
  const { classes } = useStyles()
45
44
  const { offsetPx } = model
@@ -42,25 +42,16 @@ export default class BgzipFastaMsaAdapter extends BaseAdapter {
42
42
 
43
43
  async getMSAList() {
44
44
  const refNames = await this.getMSARefs()
45
- const list = new Set<string>()
46
45
  const val = this.getConf('msaRegex')
47
46
  const re = new RegExp(val)
48
- for (let i = 0, l = refNames.length; i < l; i++) {
49
- list.add(refNames[i]!.split(re)[0]!)
50
- }
47
+ const list = new Set(refNames.map(name => name.split(re)[0]!))
51
48
  return [...list]
52
49
  }
53
50
 
54
51
  async getMSA(id: string) {
55
52
  const adapter = await this.configure()
56
53
  const refNames = await adapter.getRefNames()
57
- const rows = []
58
- for (let i = 0, l = refNames.length; i < l; i++) {
59
- const refName = refNames[i]!
60
- if (refName.startsWith(id)) {
61
- rows.push(refName)
62
- }
63
- }
54
+ const rows = refNames.filter(refName => refName.startsWith(id))
64
55
  return firstValueFrom(
65
56
  adapter
66
57
  .getFeaturesInMultipleRegions(
@@ -35,6 +35,21 @@ const useStyles = makeStyles()({
35
35
  textAreaFont: {
36
36
  fontFamily: 'Courier New',
37
37
  },
38
+ inputContainer: {
39
+ marginBottom: 30,
40
+ },
41
+ fileContainer: {
42
+ maxWidth: 500,
43
+ },
44
+ msaInput: {
45
+ marginBottom: 20,
46
+ },
47
+ queryNameInput: {
48
+ marginTop: 20,
49
+ },
50
+ warningAlert: {
51
+ marginTop: 10,
52
+ },
38
53
  })
39
54
 
40
55
  const ManualMSALoader = observer(function PreLoadedMSA2({
@@ -91,9 +106,9 @@ const ManualMSALoader = observer(function PreLoadedMSA2({
91
106
  </RadioGroup>
92
107
  </FormControl>
93
108
 
94
- <div style={{ marginBottom: 30 }}>
109
+ <div className={classes.inputContainer}>
95
110
  {inputMethod === 'file' ? (
96
- <div style={{ maxWidth: 500 }}>
111
+ <div className={classes.fileContainer}>
97
112
  <FileSelector
98
113
  name="MSA File .aln (Clustal), .fa/.mfa (aligned FASTA), .stock (Stockholm), etc)"
99
114
  inline
@@ -114,7 +129,7 @@ const ManualMSALoader = observer(function PreLoadedMSA2({
114
129
  name="MSA"
115
130
  multiline
116
131
  minRows={5}
117
- style={{ marginBottom: '20px' }}
132
+ className={classes.msaInput}
118
133
  maxRows={10}
119
134
  fullWidth
120
135
  placeholder="Paste MSA here"
@@ -154,7 +169,7 @@ const ManualMSALoader = observer(function PreLoadedMSA2({
154
169
  name="MSA row name"
155
170
  fullWidth
156
171
  required
157
- style={{ marginTop: 20 }}
172
+ className={classes.queryNameInput}
158
173
  placeholder="Row name in MSA that corresponds to the selected transcript"
159
174
  helperText="Required: Specify the name of the row in your MSA that should be aligned with the selected transcript"
160
175
  value={querySeqName}
@@ -163,13 +178,13 @@ const ManualMSALoader = observer(function PreLoadedMSA2({
163
178
  }}
164
179
  />
165
180
 
166
- {!querySeqName.trim() && (
167
- <Alert severity="warning" style={{ marginTop: 10 }}>
181
+ {!querySeqName.trim() ? (
182
+ <Alert severity="warning" className={classes.warningAlert}>
168
183
  Without specifying the MSA row name, clicking on the MSA will not
169
184
  navigate to the corresponding genome position, and hovering
170
185
  highlights will not work.
171
186
  </Alert>
172
- )}
187
+ ) : null}
173
188
  </DialogContent>
174
189
 
175
190
  <DialogActions>
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useMemo, useState } from 'react'
1
+ import React, { useMemo, useState } from 'react'
2
2
 
3
3
  import { ErrorMessage } from '@jbrowse/core/ui'
4
4
  import { getContainingView } from '@jbrowse/core/util'
@@ -13,19 +13,29 @@ import {
13
13
  Typography,
14
14
  } from '@mui/material'
15
15
  import { observer } from 'mobx-react'
16
+ import { makeStyles } from 'tss-react/mui'
16
17
 
17
18
  import { blastLaunchViewFromCache } from './blastLaunchView'
18
- import {
19
- clearAllCachedResults,
20
- deleteCachedResult,
21
- getAllCachedResults,
22
- } from '../../../utils/blastCache'
19
+ import { useCachedBlastResults } from './useCachedBlastResults'
23
20
  import { getGeneIdentifiers } from '../../util'
24
21
 
25
22
  import type { CachedBlastResult } from '../../../utils/blastCache'
26
23
  import type { AbstractTrackModel, Feature } from '@jbrowse/core/util'
27
24
  import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
28
25
 
26
+ const useStyles = makeStyles()({
27
+ header: {
28
+ display: 'flex',
29
+ justifyContent: 'space-between',
30
+ alignItems: 'center',
31
+ marginBottom: 8,
32
+ },
33
+ resultList: {
34
+ maxHeight: 300,
35
+ overflow: 'auto',
36
+ },
37
+ })
38
+
29
39
  function getResultDisplayName(result: CachedBlastResult): string {
30
40
  const parts = []
31
41
  if (result.geneName) {
@@ -49,44 +59,14 @@ const CachedBlastResults = observer(function ({
49
59
  handleClose: () => void
50
60
  feature: Feature
51
61
  }) {
52
- const [results, setResults] = useState<CachedBlastResult[]>([])
53
- const [loading, setLoading] = useState(true)
54
- const [error, setError] = useState<unknown>()
62
+ const { classes } = useStyles()
55
63
  const view = getContainingView(model) as LinearGenomeViewModel
64
+ const [operationError, setOperationError] = useState<unknown>()
56
65
 
57
66
  const geneIds = useMemo(() => getGeneIdentifiers(feature), [feature])
58
67
 
59
- useEffect(() => {
60
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
61
- ;(async () => {
62
- try {
63
- const cached = await getAllCachedResults()
64
- setResults(cached.filter(r => r.geneId && geneIds.includes(r.geneId)))
65
- setLoading(false)
66
- } catch (e) {
67
- console.error(e)
68
- setError(e)
69
- }
70
- })()
71
- }, [geneIds])
72
-
73
- const handleDelete = async (id: string) => {
74
- try {
75
- await deleteCachedResult(id)
76
- setResults(r => r.filter(result => result.id !== id))
77
- } catch (e) {
78
- setError(e)
79
- }
80
- }
81
-
82
- const handleClearAll = async () => {
83
- try {
84
- await clearAllCachedResults()
85
- setResults([])
86
- } catch (e) {
87
- setError(e)
88
- }
89
- }
68
+ const { results, error, isLoading, handleDelete, handleClearAll } =
69
+ useCachedBlastResults(geneIds)
90
70
 
91
71
  const handleUseCached = (cached: CachedBlastResult) => {
92
72
  blastLaunchViewFromCache({
@@ -97,11 +77,12 @@ const CachedBlastResults = observer(function ({
97
77
  handleClose()
98
78
  }
99
79
 
100
- if (error) {
101
- return <ErrorMessage error={error} />
80
+ const displayError = error ?? operationError
81
+ if (displayError) {
82
+ return <ErrorMessage error={displayError} />
102
83
  }
103
84
 
104
- if (loading) {
85
+ if (isLoading) {
105
86
  return <Typography>Loading cached results...</Typography>
106
87
  }
107
88
 
@@ -116,29 +97,26 @@ const CachedBlastResults = observer(function ({
116
97
 
117
98
  return (
118
99
  <div>
119
- <div
120
- style={{
121
- display: 'flex',
122
- justifyContent: 'space-between',
123
- alignItems: 'center',
124
- marginBottom: 8,
125
- }}
126
- >
100
+ <div className={classes.header}>
127
101
  <Typography variant="subtitle1">
128
102
  Cached BLAST Results ({results.length})
129
103
  </Typography>
130
104
  <Button
131
105
  size="small"
132
106
  color="error"
133
- onClick={() => {
134
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
135
- handleClearAll()
107
+ onClick={async () => {
108
+ try {
109
+ setOperationError(undefined)
110
+ await handleClearAll()
111
+ } catch (e) {
112
+ setOperationError(e)
113
+ }
136
114
  }}
137
115
  >
138
116
  Clear All
139
117
  </Button>
140
118
  </div>
141
- <List dense style={{ maxHeight: 300, overflow: 'auto' }}>
119
+ <List dense className={classes.resultList}>
142
120
  {results.map(result => (
143
121
  <ListItem
144
122
  key={result.id}
@@ -147,10 +125,14 @@ const CachedBlastResults = observer(function ({
147
125
  <IconButton
148
126
  edge="end"
149
127
  size="small"
150
- onClick={e => {
128
+ onClick={async e => {
151
129
  e.stopPropagation()
152
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
153
- handleDelete(result.id)
130
+ try {
131
+ setOperationError(undefined)
132
+ await handleDelete(result.id)
133
+ } catch (err) {
134
+ setOperationError(err)
135
+ }
154
136
  }}
155
137
  >
156
138
  <DeleteIcon fontSize="small" />
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useMemo, useState } from 'react'
1
+ import React, { useMemo, useState } from 'react'
2
2
 
3
3
  import { ErrorMessage } from '@jbrowse/core/ui'
4
4
  import { getContainingView } from '@jbrowse/core/util'
@@ -19,8 +19,8 @@ import { makeStyles } from 'tss-react/mui'
19
19
  import CachedBlastResults from './CachedBlastResults'
20
20
  import { blastLaunchView } from './blastLaunchView'
21
21
  import { msaAlgorithms } from './consts'
22
+ import { useCachedBlastResults } from './useCachedBlastResults'
22
23
  import TextField2 from '../../../components/TextField2'
23
- import { getAllCachedResults } from '../../../utils/blastCache'
24
24
  import {
25
25
  getGeneDisplayName,
26
26
  getGeneIdentifiers,
@@ -83,24 +83,10 @@ const NCBIBlastAutomaticPanel = observer(function ({
83
83
  useState<MsaAlgorithm>('clustalo')
84
84
  const [selectedBlastProgram, setSelectedBlastProgram] =
85
85
  useState<blastProgramsT>('quick-blastp')
86
- const [hasCachedResults, setHasCachedResults] = useState(false)
87
- const [error, setError] = useState<unknown>()
88
86
 
89
87
  const geneIds = useMemo(() => getGeneIdentifiers(feature), [feature])
90
- useEffect(() => {
91
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
92
- ;(async () => {
93
- try {
94
- const results = await getAllCachedResults()
95
- setHasCachedResults(
96
- results.some(r => r.geneId && geneIds.includes(r.geneId)),
97
- )
98
- } catch (e) {
99
- console.error(e)
100
- setError(e)
101
- }
102
- })()
103
- }, [geneIds])
88
+ const { results: cachedResults, error: cachedResultsError } =
89
+ useCachedBlastResults(geneIds)
104
90
 
105
91
  const {
106
92
  options,
@@ -110,7 +96,7 @@ const NCBIBlastAutomaticPanel = observer(function ({
110
96
  proteinSequence,
111
97
  error: proteinSequenceError,
112
98
  } = useTranscriptSelection({ feature, view })
113
- const e = proteinSequenceError ?? launchViewError ?? error
99
+ const e = proteinSequenceError ?? launchViewError ?? cachedResultsError
114
100
  return (
115
101
  <>
116
102
  <DialogContent className={classes.dialogContent}>
@@ -205,7 +191,7 @@ const NCBIBlastAutomaticPanel = observer(function ({
205
191
  submitting BLAST yourself and downloading the resulting files
206
192
  </Typography>
207
193
 
208
- {hasCachedResults ? (
194
+ {cachedResults.length > 0 ? (
209
195
  <Accordion className={classes.cachedResultsAccordion}>
210
196
  <AccordionSummary expandIcon={<ExpandMoreIcon />}>
211
197
  <Typography>Previous BLAST Results</Typography>
@@ -243,18 +229,23 @@ const NCBIBlastAutomaticPanel = observer(function ({
243
229
  proteinSequence,
244
230
  },
245
231
  })
232
+ handleClose()
246
233
  } catch (e) {
247
234
  console.error(e)
248
235
  setLaunchViewError(e)
249
236
  }
250
-
251
- handleClose()
252
237
  }}
253
238
  disabled={!proteinSequence}
254
239
  >
255
240
  Submit
256
241
  </Button>
257
- <Button color="secondary" variant="contained" onClick={handleClose}>
242
+ <Button
243
+ color="secondary"
244
+ variant="contained"
245
+ onClick={() => {
246
+ handleClose()
247
+ }}
248
+ >
258
249
  Cancel
259
250
  </Button>
260
251
  </DialogActions>
@@ -26,6 +26,9 @@ const useStyles = makeStyles()({
26
26
  margin: 30,
27
27
  maxWidth: 600,
28
28
  },
29
+ infoText: {
30
+ marginTop: 20,
31
+ },
29
32
  })
30
33
 
31
34
  const NCBIBlastManualPanel = observer(function ({
@@ -77,7 +80,7 @@ const NCBIBlastManualPanel = observer(function ({
77
80
  </div>
78
81
  ) : null}
79
82
 
80
- <Typography style={{ marginTop: 20 }}>
83
+ <Typography className={classes.infoText}>
81
84
  Click the link above and run your BLAST query, and once you have
82
85
  results, click "Multiple Alignment" at the top of the results page to
83
86
  be redirected to COBALT, NCBI's multiple sequence aligner. Once COBALT
@@ -3,6 +3,7 @@ import React, { useState } from 'react'
3
3
  import { useLocalStorage } from '@jbrowse/core/util'
4
4
  import SettingsIcon from '@mui/icons-material/Settings'
5
5
  import { IconButton } from '@mui/material'
6
+ import { makeStyles } from 'tss-react/mui'
6
7
 
7
8
  import NCBIBlastAutomaticPanel from './NCBIBlastAutomaticPanel'
8
9
  import NCBIBlastManualPanel from './NCBIBlastManualPanel'
@@ -13,6 +14,12 @@ import { BASE_BLAST_URL } from './consts'
13
14
 
14
15
  import type { AbstractTrackModel, Feature } from '@jbrowse/core/util'
15
16
 
17
+ const useStyles = makeStyles()({
18
+ settingsButton: {
19
+ float: 'right',
20
+ },
21
+ })
22
+
16
23
  const panelMap = {
17
24
  automatic: NCBIBlastAutomaticPanel,
18
25
  rid: NCBIBlastRIDPanel,
@@ -34,13 +41,14 @@ export default function NCBIBlastPanel({
34
41
  BASE_BLAST_URL,
35
42
  )
36
43
  const [settingsOpen, setSettingsOpen] = useState(false)
44
+ const { classes } = useStyles()
37
45
 
38
46
  const Panel = panelMap[lookupMethod as keyof typeof panelMap]
39
47
 
40
48
  return (
41
49
  <>
42
50
  <IconButton
43
- style={{ float: 'right' }}
51
+ className={classes.settingsButton}
44
52
  size="small"
45
53
  onClick={() => {
46
54
  setSettingsOpen(true)
@@ -28,6 +28,15 @@ const useStyles = makeStyles()({
28
28
  dialogContent: {
29
29
  width: '80em',
30
30
  },
31
+ marginBottom: {
32
+ marginBottom: 16,
33
+ },
34
+ ridField: {
35
+ width: 150,
36
+ },
37
+ infoText: {
38
+ marginTop: 20,
39
+ },
31
40
  })
32
41
 
33
42
  const NCBIBlastRIDPanel = observer(function ({
@@ -60,7 +69,6 @@ const NCBIBlastRIDPanel = observer(function ({
60
69
  } = useTranscriptSelection({ feature, view })
61
70
 
62
71
  const e = proteinSequenceError ?? launchViewError
63
- const style = { width: 150 }
64
72
  const trimmedRid = rid.trim()
65
73
 
66
74
  return (
@@ -69,7 +77,7 @@ const NCBIBlastRIDPanel = observer(function ({
69
77
  {children}
70
78
  {e ? <ErrorMessage error={e} /> : null}
71
79
 
72
- <Typography variant="body2" style={{ marginBottom: 16 }}>
80
+ <Typography variant="body2" className={classes.marginBottom}>
73
81
  Enter the RID (Request ID) from a previously submitted NCBI BLAST
74
82
  query. You can find the RID in the BLAST results page URL or at the
75
83
  top of the results page. RIDs are typically valid for 24-36 hours
@@ -81,7 +89,7 @@ const NCBIBlastRIDPanel = observer(function ({
81
89
  label="BLAST RID"
82
90
  placeholder="e.g., ABC12345"
83
91
  fullWidth
84
- style={{ marginBottom: 16 }}
92
+ className={classes.marginBottom}
85
93
  value={rid}
86
94
  onChange={event => {
87
95
  setRid(event.target.value)
@@ -89,7 +97,7 @@ const NCBIBlastRIDPanel = observer(function ({
89
97
  />
90
98
 
91
99
  {trimmedRid ? (
92
- <Typography variant="body2" style={{ marginBottom: 16 }}>
100
+ <Typography variant="body2" className={classes.marginBottom}>
93
101
  <ExternalLink href={`${baseUrl}?CMD=Get&RID=${trimmedRid}`}>
94
102
  View BLAST results on NCBI
95
103
  </ExternalLink>
@@ -99,7 +107,7 @@ const NCBIBlastRIDPanel = observer(function ({
99
107
  <TextField2
100
108
  variant="outlined"
101
109
  label="MSA Algorithm"
102
- style={style}
110
+ className={classes.ridField}
103
111
  select
104
112
  value={selectedMsaAlgorithm}
105
113
  onChange={event => {
@@ -122,7 +130,7 @@ const NCBIBlastRIDPanel = observer(function ({
122
130
  proteinSequence={proteinSequence}
123
131
  />
124
132
 
125
- <Typography style={{ marginTop: 20 }}>
133
+ <Typography className={classes.infoText}>
126
134
  This will fetch the BLAST results for the provided RID and run them
127
135
  through a multiple sequence alignment. The protein sequence from the
128
136
  selected transcript will be added as the query sequence in the MSA.
@@ -152,12 +160,11 @@ const NCBIBlastRIDPanel = observer(function ({
152
160
  rid: trimmedRid,
153
161
  },
154
162
  })
163
+ handleClose()
155
164
  } catch (e) {
156
165
  console.error(e)
157
166
  setLaunchViewError(e)
158
167
  }
159
-
160
- handleClose()
161
168
  }}
162
169
  disabled={!proteinSequence || !trimmedRid}
163
170
  >
@@ -7,10 +7,17 @@ import {
7
7
  DialogContent,
8
8
  DialogTitle,
9
9
  } from '@mui/material'
10
+ import { makeStyles } from 'tss-react/mui'
10
11
 
11
12
  import { BASE_BLAST_URL } from './consts'
12
13
  import TextField2 from '../../../components/TextField2'
13
14
 
15
+ const useStyles = makeStyles()({
16
+ urlField: {
17
+ minWidth: 300,
18
+ },
19
+ })
20
+
14
21
  export default function NCBISettingsDialog({
15
22
  handleClose,
16
23
  baseUrl,
@@ -18,6 +25,7 @@ export default function NCBISettingsDialog({
18
25
  handleClose: (arg?: string) => void
19
26
  baseUrl: string
20
27
  }) {
28
+ const { classes } = useStyles()
21
29
  const [tempBaseUrl, setTempBaseUrl] = useState(baseUrl)
22
30
  return (
23
31
  <Dialog
@@ -36,7 +44,7 @@ export default function NCBISettingsDialog({
36
44
  fullWidth
37
45
  variant="outlined"
38
46
  value={tempBaseUrl}
39
- style={{ minWidth: '300px' }}
47
+ className={classes.urlField}
40
48
  onChange={e => {
41
49
  setTempBaseUrl(e.target.value)
42
50
  }}