jbrowse-plugin-msaview 2.3.5 → 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.
- package/README.md +15 -216
- package/dist/AddHighlightModel/GenomeMouseoverHighlight.js.map +1 -1
- package/dist/LaunchMsaView/components/ManualMSALoader/ManualMSALoader.js +19 -4
- package/dist/LaunchMsaView/components/ManualMSALoader/ManualMSALoader.js.map +1 -1
- package/dist/LaunchMsaView/components/NCBIBlastQuery/CachedBlastResults.js +16 -7
- package/dist/LaunchMsaView/components/NCBIBlastQuery/CachedBlastResults.js.map +1 -1
- package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastAutomaticPanel.js +4 -2
- package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastAutomaticPanel.js.map +1 -1
- package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastManualPanel.js +4 -1
- package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastManualPanel.js.map +1 -1
- package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastPanel.js +8 -1
- package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastPanel.js.map +1 -1
- package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastRIDPanel.js +15 -7
- package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastRIDPanel.js.map +1 -1
- package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBISettingsDialog.js +8 -1
- package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBISettingsDialog.js.map +1 -1
- package/dist/LaunchMsaView/components/NCBIBlastQuery/useCachedBlastResults.js +3 -0
- package/dist/LaunchMsaView/components/NCBIBlastQuery/useCachedBlastResults.js.map +1 -1
- package/dist/LaunchMsaView/components/PreLoadedMSA/PreLoadedMSADataPanel.js +7 -2
- package/dist/LaunchMsaView/components/PreLoadedMSA/PreLoadedMSADataPanel.js.map +1 -1
- package/dist/LaunchMsaView/components/TabPanel.js +1 -1
- package/dist/LaunchMsaView/components/TabPanel.js.map +1 -1
- package/dist/LaunchMsaView/components/TranscriptSelector.js +7 -3
- package/dist/LaunchMsaView/components/TranscriptSelector.js.map +1 -1
- package/dist/MsaViewPanel/afterCreateAutoruns.js +9 -15
- package/dist/MsaViewPanel/afterCreateAutoruns.js.map +1 -1
- package/dist/MsaViewPanel/components/ConnectStructureDialog.js +15 -10
- package/dist/MsaViewPanel/components/ConnectStructureDialog.js.map +1 -1
- package/dist/MsaViewPanel/components/MsaViewPanel.js +8 -1
- package/dist/MsaViewPanel/components/MsaViewPanel.js.map +1 -1
- package/dist/MsaViewPanel/model.d.ts +2 -2
- package/dist/MsaViewPanel/model.js +13 -10
- package/dist/MsaViewPanel/model.js.map +1 -1
- package/dist/MsaViewPanel/pairwiseAlignment.js +6 -6
- package/dist/MsaViewPanel/pairwiseAlignment.js.map +1 -1
- package/dist/MsaViewPanel/structureConnection.d.ts +22 -0
- package/dist/MsaViewPanel/structureConnection.js +4 -0
- package/dist/MsaViewPanel/structureConnection.js.map +1 -1
- package/dist/jbrowse-plugin-msaview.umd.production.min.js +24 -24
- package/dist/jbrowse-plugin-msaview.umd.production.min.js.map +4 -4
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -4
- package/src/AddHighlightModel/GenomeMouseoverHighlight.tsx +1 -2
- package/src/LaunchMsaView/components/ManualMSALoader/ManualMSALoader.tsx +22 -7
- package/src/LaunchMsaView/components/NCBIBlastQuery/CachedBlastResults.tsx +17 -9
- package/src/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastAutomaticPanel.tsx +8 -3
- package/src/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastManualPanel.tsx +4 -1
- package/src/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastPanel.tsx +9 -1
- package/src/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastRIDPanel.tsx +15 -8
- package/src/LaunchMsaView/components/NCBIBlastQuery/NCBISettingsDialog.tsx +9 -1
- package/src/LaunchMsaView/components/NCBIBlastQuery/useCachedBlastResults.ts +3 -0
- package/src/LaunchMsaView/components/PreLoadedMSA/PreLoadedMSADataPanel.tsx +11 -2
- package/src/LaunchMsaView/components/TabPanel.tsx +1 -1
- package/src/LaunchMsaView/components/TranscriptSelector.tsx +7 -3
- package/src/MsaViewPanel/afterCreateAutoruns.ts +9 -27
- package/src/MsaViewPanel/components/ConnectStructureDialog.tsx +23 -25
- package/src/MsaViewPanel/components/MsaViewPanel.tsx +9 -1
- package/src/MsaViewPanel/model.ts +23 -18
- package/src/MsaViewPanel/pairwiseAlignment.ts +6 -6
- package/src/MsaViewPanel/structureConnection.ts +23 -0
- package/src/version.ts +1 -1
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "2.3.
|
|
1
|
+
export declare const version = "2.3.8";
|
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const version = '2.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.
|
|
2
|
+
"version": "2.3.8",
|
|
3
3
|
"license": "MIT",
|
|
4
4
|
"name": "jbrowse-plugin-msaview",
|
|
5
5
|
"repository": {
|
|
@@ -73,8 +73,6 @@
|
|
|
73
73
|
"test:setup:version": "node scripts/test-versions.mjs setup",
|
|
74
74
|
"test:versions": "node scripts/test-versions.mjs run",
|
|
75
75
|
"test:version": "node scripts/test-versions.mjs run",
|
|
76
|
-
"
|
|
77
|
-
"version": "node -e \"console.log('export const version = \\'' + require('./package.json').version + '\\'')\" > src/version.ts && git add src/version.ts",
|
|
78
|
-
"postversion": "git push --follow-tags"
|
|
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
|
|
@@ -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
|
|
109
|
+
<div className={classes.inputContainer}>
|
|
95
110
|
{inputMethod === 'file' ? (
|
|
96
|
-
<div
|
|
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
|
-
|
|
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
|
-
|
|
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"
|
|
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>
|
|
@@ -13,6 +13,7 @@ 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
19
|
import { useCachedBlastResults } from './useCachedBlastResults'
|
|
@@ -22,6 +23,19 @@ import type { CachedBlastResult } from '../../../utils/blastCache'
|
|
|
22
23
|
import type { AbstractTrackModel, Feature } from '@jbrowse/core/util'
|
|
23
24
|
import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
|
|
24
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
|
+
|
|
25
39
|
function getResultDisplayName(result: CachedBlastResult): string {
|
|
26
40
|
const parts = []
|
|
27
41
|
if (result.geneName) {
|
|
@@ -45,6 +59,7 @@ const CachedBlastResults = observer(function ({
|
|
|
45
59
|
handleClose: () => void
|
|
46
60
|
feature: Feature
|
|
47
61
|
}) {
|
|
62
|
+
const { classes } = useStyles()
|
|
48
63
|
const view = getContainingView(model) as LinearGenomeViewModel
|
|
49
64
|
const [operationError, setOperationError] = useState<unknown>()
|
|
50
65
|
|
|
@@ -82,14 +97,7 @@ const CachedBlastResults = observer(function ({
|
|
|
82
97
|
|
|
83
98
|
return (
|
|
84
99
|
<div>
|
|
85
|
-
<div
|
|
86
|
-
style={{
|
|
87
|
-
display: 'flex',
|
|
88
|
-
justifyContent: 'space-between',
|
|
89
|
-
alignItems: 'center',
|
|
90
|
-
marginBottom: 8,
|
|
91
|
-
}}
|
|
92
|
-
>
|
|
100
|
+
<div className={classes.header}>
|
|
93
101
|
<Typography variant="subtitle1">
|
|
94
102
|
Cached BLAST Results ({results.length})
|
|
95
103
|
</Typography>
|
|
@@ -108,7 +116,7 @@ const CachedBlastResults = observer(function ({
|
|
|
108
116
|
Clear All
|
|
109
117
|
</Button>
|
|
110
118
|
</div>
|
|
111
|
-
<List dense
|
|
119
|
+
<List dense className={classes.resultList}>
|
|
112
120
|
{results.map(result => (
|
|
113
121
|
<ListItem
|
|
114
122
|
key={result.id}
|
|
@@ -229,18 +229,23 @@ const NCBIBlastAutomaticPanel = observer(function ({
|
|
|
229
229
|
proteinSequence,
|
|
230
230
|
},
|
|
231
231
|
})
|
|
232
|
+
handleClose()
|
|
232
233
|
} catch (e) {
|
|
233
234
|
console.error(e)
|
|
234
235
|
setLaunchViewError(e)
|
|
235
236
|
}
|
|
236
|
-
|
|
237
|
-
handleClose()
|
|
238
237
|
}}
|
|
239
238
|
disabled={!proteinSequence}
|
|
240
239
|
>
|
|
241
240
|
Submit
|
|
242
241
|
</Button>
|
|
243
|
-
<Button
|
|
242
|
+
<Button
|
|
243
|
+
color="secondary"
|
|
244
|
+
variant="contained"
|
|
245
|
+
onClick={() => {
|
|
246
|
+
handleClose()
|
|
247
|
+
}}
|
|
248
|
+
>
|
|
244
249
|
Cancel
|
|
245
250
|
</Button>
|
|
246
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
|
|
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
|
-
|
|
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"
|
|
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
|
-
|
|
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"
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
47
|
+
className={classes.urlField}
|
|
40
48
|
onChange={e => {
|
|
41
49
|
setTempBaseUrl(e.target.value)
|
|
42
50
|
}}
|
|
@@ -10,6 +10,9 @@ const swrConfig = {
|
|
|
10
10
|
revalidateOnFocus: false,
|
|
11
11
|
revalidateOnReconnect: false,
|
|
12
12
|
revalidateIfStale: false,
|
|
13
|
+
refreshWhenHidden: false,
|
|
14
|
+
refreshWhenOffline: false,
|
|
15
|
+
shouldRetryOnError: false,
|
|
13
16
|
}
|
|
14
17
|
|
|
15
18
|
export function useCachedBlastResults(geneIds: string[]) {
|
|
@@ -24,6 +24,9 @@ const useStyles = makeStyles()({
|
|
|
24
24
|
dialogContent: {
|
|
25
25
|
width: '80em',
|
|
26
26
|
},
|
|
27
|
+
selectedContainer: {
|
|
28
|
+
marginTop: 50,
|
|
29
|
+
},
|
|
27
30
|
})
|
|
28
31
|
|
|
29
32
|
const PreLoadedMSA = observer(function ({
|
|
@@ -120,7 +123,7 @@ const PreLoadedMSA = observer(function ({
|
|
|
120
123
|
</TextField2>
|
|
121
124
|
|
|
122
125
|
{selectedDataset ? (
|
|
123
|
-
<div
|
|
126
|
+
<div className={classes.selectedContainer}>
|
|
124
127
|
{!msaListLoading && msaDataLoading ? (
|
|
125
128
|
<LoadingEllipses
|
|
126
129
|
variant="h6"
|
|
@@ -183,7 +186,13 @@ const PreLoadedMSA = observer(function ({
|
|
|
183
186
|
>
|
|
184
187
|
Submit
|
|
185
188
|
</Button>
|
|
186
|
-
<Button
|
|
189
|
+
<Button
|
|
190
|
+
color="secondary"
|
|
191
|
+
variant="contained"
|
|
192
|
+
onClick={() => {
|
|
193
|
+
handleClose()
|
|
194
|
+
}}
|
|
195
|
+
>
|
|
187
196
|
Cancel
|
|
188
197
|
</Button>
|
|
189
198
|
</DialogActions>
|
|
@@ -21,6 +21,10 @@ const useStyles = makeStyles()({
|
|
|
21
21
|
minWidth: {
|
|
22
22
|
minWidth: 300,
|
|
23
23
|
},
|
|
24
|
+
centered: {
|
|
25
|
+
alignContent: 'center',
|
|
26
|
+
marginLeft: 20,
|
|
27
|
+
},
|
|
24
28
|
})
|
|
25
29
|
|
|
26
30
|
export default function TranscriptSelector({
|
|
@@ -70,7 +74,7 @@ export default function TranscriptSelector({
|
|
|
70
74
|
)
|
|
71
75
|
})}
|
|
72
76
|
</TextField>
|
|
73
|
-
<div
|
|
77
|
+
<div className={classes.centered}>
|
|
74
78
|
<Button
|
|
75
79
|
variant="contained"
|
|
76
80
|
color="primary"
|
|
@@ -83,7 +87,7 @@ export default function TranscriptSelector({
|
|
|
83
87
|
</div>
|
|
84
88
|
</div>
|
|
85
89
|
|
|
86
|
-
{showSequence
|
|
90
|
+
{showSequence ? (
|
|
87
91
|
<ReadOnlyTextField2
|
|
88
92
|
value={
|
|
89
93
|
proteinSequence
|
|
@@ -91,7 +95,7 @@ export default function TranscriptSelector({
|
|
|
91
95
|
: 'Loading...'
|
|
92
96
|
}
|
|
93
97
|
/>
|
|
94
|
-
)}
|
|
98
|
+
) : null}
|
|
95
99
|
</>
|
|
96
100
|
)
|
|
97
101
|
}
|
|
@@ -8,27 +8,11 @@ import {
|
|
|
8
8
|
retrieveMsaData,
|
|
9
9
|
storeMsaData,
|
|
10
10
|
} from './msaDataStore'
|
|
11
|
-
import { gappedToUngappedPosition } from './structureConnection'
|
|
11
|
+
import { gappedToUngappedPosition, isProteinView } from './structureConnection'
|
|
12
12
|
import { getUniprotIdFromAlphaFoldUrl } from './util'
|
|
13
13
|
|
|
14
14
|
import type { JBrowsePluginMsaViewModel } from './model'
|
|
15
15
|
|
|
16
|
-
interface ProteinView {
|
|
17
|
-
type: 'ProteinView'
|
|
18
|
-
id: string
|
|
19
|
-
structures: {
|
|
20
|
-
connectedViewId?: string
|
|
21
|
-
uniprotId?: string
|
|
22
|
-
structureSequences?: unknown[]
|
|
23
|
-
hoverGenomeHighlights?: { start: number; end: number }[]
|
|
24
|
-
}[]
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function isProteinView(view: unknown): view is ProteinView {
|
|
28
|
-
const v = view as Record<string, unknown>
|
|
29
|
-
return v.type === 'ProteinView' && Array.isArray(v.structures)
|
|
30
|
-
}
|
|
31
|
-
|
|
32
16
|
export function loadStoredData(self: JBrowsePluginMsaViewModel) {
|
|
33
17
|
const { dataStoreId, rows } = self
|
|
34
18
|
if (dataStoreId && rows.length === 0) {
|
|
@@ -179,7 +163,7 @@ export function highlightConnectedStructures(self: JBrowsePluginMsaViewModel) {
|
|
|
179
163
|
}
|
|
180
164
|
|
|
181
165
|
for (const conn of connectedProteinViews) {
|
|
182
|
-
const structure = conn.proteinView
|
|
166
|
+
const structure = conn.proteinView.structures[conn.structureIdx]
|
|
183
167
|
if (!structure) {
|
|
184
168
|
continue
|
|
185
169
|
}
|
|
@@ -210,7 +194,7 @@ export function highlightConnectedStructures(self: JBrowsePluginMsaViewModel) {
|
|
|
210
194
|
}
|
|
211
195
|
|
|
212
196
|
export function autoConnectStructures(self: JBrowsePluginMsaViewModel) {
|
|
213
|
-
const
|
|
197
|
+
const views = getSession(self).views as unknown[]
|
|
214
198
|
const { connectedViewId, uniprotId, rows, connectedStructures } = self
|
|
215
199
|
|
|
216
200
|
if (!uniprotId || rows.length === 0) {
|
|
@@ -221,14 +205,13 @@ export function autoConnectStructures(self: JBrowsePluginMsaViewModel) {
|
|
|
221
205
|
if (!isProteinView(view)) {
|
|
222
206
|
continue
|
|
223
207
|
}
|
|
224
|
-
const v = view
|
|
225
208
|
|
|
226
209
|
for (
|
|
227
210
|
let structureIdx = 0;
|
|
228
|
-
structureIdx <
|
|
211
|
+
structureIdx < view.structures.length;
|
|
229
212
|
structureIdx++
|
|
230
213
|
) {
|
|
231
|
-
const structure =
|
|
214
|
+
const structure = view.structures[structureIdx]
|
|
232
215
|
if (!structure) {
|
|
233
216
|
continue
|
|
234
217
|
}
|
|
@@ -242,7 +225,7 @@ export function autoConnectStructures(self: JBrowsePluginMsaViewModel) {
|
|
|
242
225
|
}
|
|
243
226
|
|
|
244
227
|
const alreadyConnected = connectedStructures.some(
|
|
245
|
-
c => c.proteinViewId ===
|
|
228
|
+
c => c.proteinViewId === view.id && c.structureIdx === structureIdx,
|
|
246
229
|
)
|
|
247
230
|
if (alreadyConnected) {
|
|
248
231
|
continue
|
|
@@ -253,7 +236,7 @@ export function autoConnectStructures(self: JBrowsePluginMsaViewModel) {
|
|
|
253
236
|
}
|
|
254
237
|
|
|
255
238
|
try {
|
|
256
|
-
self.connectToStructure(
|
|
239
|
+
self.connectToStructure(view.id, structureIdx)
|
|
257
240
|
} catch (e) {
|
|
258
241
|
console.error('Failed to auto-connect to ProteinView:', e)
|
|
259
242
|
}
|
|
@@ -262,7 +245,7 @@ export function autoConnectStructures(self: JBrowsePluginMsaViewModel) {
|
|
|
262
245
|
}
|
|
263
246
|
|
|
264
247
|
export function observeProteinHighlights(self: JBrowsePluginMsaViewModel) {
|
|
265
|
-
const
|
|
248
|
+
const views = getSession(self).views as unknown[]
|
|
266
249
|
const { connectedViewId, transcriptToMsaMap, querySeqName } = self
|
|
267
250
|
|
|
268
251
|
if (!connectedViewId || !transcriptToMsaMap) {
|
|
@@ -275,9 +258,8 @@ export function observeProteinHighlights(self: JBrowsePluginMsaViewModel) {
|
|
|
275
258
|
if (!isProteinView(view)) {
|
|
276
259
|
continue
|
|
277
260
|
}
|
|
278
|
-
const v = view
|
|
279
261
|
|
|
280
|
-
for (const structure of
|
|
262
|
+
for (const structure of view.structures) {
|
|
281
263
|
if (structure.connectedViewId !== connectedViewId) {
|
|
282
264
|
continue
|
|
283
265
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useState } from 'react'
|
|
2
2
|
|
|
3
|
-
import { Dialog } from '@jbrowse/core/ui'
|
|
3
|
+
import { Dialog, ErrorMessage } from '@jbrowse/core/ui'
|
|
4
4
|
import { getSession } from '@jbrowse/core/util'
|
|
5
5
|
import {
|
|
6
6
|
Button,
|
|
@@ -13,9 +13,18 @@ import {
|
|
|
13
13
|
Typography,
|
|
14
14
|
} from '@mui/material'
|
|
15
15
|
import { observer } from 'mobx-react'
|
|
16
|
+
import { makeStyles } from 'tss-react/mui'
|
|
17
|
+
|
|
18
|
+
import { isProteinView } from '../structureConnection'
|
|
16
19
|
|
|
17
20
|
import type { JBrowsePluginMsaViewModel } from '../model'
|
|
18
21
|
|
|
22
|
+
const useStyles = makeStyles()(theme => ({
|
|
23
|
+
formControl: {
|
|
24
|
+
marginBottom: theme.spacing(2),
|
|
25
|
+
},
|
|
26
|
+
}))
|
|
27
|
+
|
|
19
28
|
const ConnectStructureDialog = observer(function ConnectStructureDialog({
|
|
20
29
|
model,
|
|
21
30
|
handleClose,
|
|
@@ -23,23 +32,18 @@ const ConnectStructureDialog = observer(function ConnectStructureDialog({
|
|
|
23
32
|
model: JBrowsePluginMsaViewModel
|
|
24
33
|
handleClose: () => void
|
|
25
34
|
}) {
|
|
35
|
+
const { classes } = useStyles()
|
|
26
36
|
const session = getSession(model)
|
|
27
37
|
const [selectedViewId, setSelectedViewId] = useState('')
|
|
28
38
|
const [selectedStructureIdx, setSelectedStructureIdx] = useState(0)
|
|
29
39
|
const [selectedMsaRow, setSelectedMsaRow] = useState(model.querySeqName)
|
|
30
40
|
const [error, setError] = useState<string>()
|
|
31
41
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const proteinViews = session.views.filter(
|
|
35
|
-
(v: any) => v.type === 'ProteinView',
|
|
36
|
-
) as any[]
|
|
42
|
+
const proteinViews = (session.views as unknown[]).filter(isProteinView)
|
|
37
43
|
|
|
38
|
-
// Get structures for the selected view
|
|
39
44
|
const selectedView = proteinViews.find(v => v.id === selectedViewId)
|
|
40
45
|
const structures = selectedView?.structures ?? []
|
|
41
46
|
|
|
42
|
-
// Get MSA row names
|
|
43
47
|
const msaRowNames = model.rows.map(r => r[0])
|
|
44
48
|
|
|
45
49
|
const handleConnect = () => {
|
|
@@ -75,7 +79,7 @@ const ConnectStructureDialog = observer(function ConnectStructureDialog({
|
|
|
75
79
|
</Typography>
|
|
76
80
|
) : (
|
|
77
81
|
<>
|
|
78
|
-
<FormControl fullWidth
|
|
82
|
+
<FormControl fullWidth className={classes.formControl}>
|
|
79
83
|
<InputLabel>Protein View</InputLabel>
|
|
80
84
|
<Select
|
|
81
85
|
value={selectedViewId}
|
|
@@ -93,8 +97,8 @@ const ConnectStructureDialog = observer(function ConnectStructureDialog({
|
|
|
93
97
|
</Select>
|
|
94
98
|
</FormControl>
|
|
95
99
|
|
|
96
|
-
{structures.length > 1
|
|
97
|
-
<FormControl fullWidth
|
|
100
|
+
{structures.length > 1 ? (
|
|
101
|
+
<FormControl fullWidth className={classes.formControl}>
|
|
98
102
|
<InputLabel>Structure</InputLabel>
|
|
99
103
|
<Select
|
|
100
104
|
value={selectedStructureIdx}
|
|
@@ -103,18 +107,16 @@ const ConnectStructureDialog = observer(function ConnectStructureDialog({
|
|
|
103
107
|
setSelectedStructureIdx(e.target.value)
|
|
104
108
|
}}
|
|
105
109
|
>
|
|
106
|
-
{structures.map(
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
),
|
|
112
|
-
)}
|
|
110
|
+
{structures.map((structure, idx) => (
|
|
111
|
+
<MenuItem key={idx} value={idx}>
|
|
112
|
+
{structure.url ?? `Structure ${idx + 1}`}
|
|
113
|
+
</MenuItem>
|
|
114
|
+
))}
|
|
113
115
|
</Select>
|
|
114
116
|
</FormControl>
|
|
115
|
-
)}
|
|
117
|
+
) : null}
|
|
116
118
|
|
|
117
|
-
<FormControl fullWidth
|
|
119
|
+
<FormControl fullWidth className={classes.formControl}>
|
|
118
120
|
<InputLabel>MSA Row</InputLabel>
|
|
119
121
|
<Select
|
|
120
122
|
value={selectedMsaRow}
|
|
@@ -131,11 +133,7 @@ const ConnectStructureDialog = observer(function ConnectStructureDialog({
|
|
|
131
133
|
</Select>
|
|
132
134
|
</FormControl>
|
|
133
135
|
|
|
134
|
-
{error
|
|
135
|
-
<Typography color="error" sx={{ mt: 1 }}>
|
|
136
|
-
{error}
|
|
137
|
-
</Typography>
|
|
138
|
-
)}
|
|
136
|
+
{error ? <ErrorMessage error={error} /> : null}
|
|
139
137
|
</>
|
|
140
138
|
)}
|
|
141
139
|
</DialogContent>
|