Skip to content

Commit 81d19ab

Browse files
committed
Update
1 parent 606648f commit 81d19ab

8 files changed

Lines changed: 306 additions & 216 deletions

File tree

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
import React, { useState } from 'react'
2+
3+
import { Dialog, ErrorMessage, LoadingEllipses } from '@jbrowse/core/ui'
4+
import { getSession } from '@jbrowse/core/util'
5+
import {
6+
Button,
7+
DialogActions,
8+
DialogContent,
9+
TextField,
10+
ToggleButton,
11+
ToggleButtonGroup,
12+
} from '@mui/material'
13+
import { observer } from 'mobx-react'
14+
import { makeStyles } from 'tss-react/mui'
15+
16+
import { useSequences } from '../../../util/useSequences'
17+
18+
import type { LinearMafDisplayModel } from '../../stateModel'
19+
20+
const useStyles = makeStyles()({
21+
dialogContent: {
22+
width: '80em',
23+
},
24+
textAreaInput: {
25+
fontFamily: 'monospace',
26+
whiteSpace: 'pre',
27+
overflowX: 'auto',
28+
},
29+
ml: {
30+
marginLeft: 10,
31+
},
32+
})
33+
34+
const GetSequenceDialog = observer(function ({
35+
onClose,
36+
model,
37+
selectionCoords,
38+
}: {
39+
onClose: () => void
40+
model: LinearMafDisplayModel
41+
selectionCoords?: {
42+
dragStartX: number
43+
dragEndX: number
44+
}
45+
}) {
46+
const [showAllLetters, setShowAllLetters] = useState(true)
47+
const { classes } = useStyles()
48+
const { sequence, loading, error } = useSequences({
49+
model,
50+
selectionCoords,
51+
showAllLetters,
52+
})
53+
const sequenceTooLarge = sequence ? sequence.length > 1_000_000 : false
54+
55+
return (
56+
<Dialog open onClose={onClose} title="Subsequence Data" maxWidth="xl">
57+
<DialogContent>
58+
<div
59+
style={{
60+
display: 'flex',
61+
alignItems: 'center',
62+
marginBottom: '16px',
63+
}}
64+
>
65+
<ToggleButtonGroup
66+
value={showAllLetters}
67+
exclusive
68+
size="small"
69+
onChange={(_event, newDisplayMode) => {
70+
if (newDisplayMode !== null) {
71+
setShowAllLetters(newDisplayMode)
72+
}
73+
}}
74+
>
75+
<ToggleButton value={true}>Show All Letters</ToggleButton>
76+
<ToggleButton value={false}>Show Only Differences</ToggleButton>
77+
</ToggleButtonGroup>
78+
<div style={{ flexGrow: 1 }} />
79+
<Button
80+
variant="contained"
81+
color="primary"
82+
disabled={loading || !sequence}
83+
onClick={() => {
84+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
85+
;(async () => {
86+
try {
87+
await navigator.clipboard.writeText(sequence)
88+
getSession(model).notify(
89+
'Sequence copied to clipboard',
90+
'info',
91+
)
92+
} catch (e) {
93+
console.error(e)
94+
getSession(model).notifyError(`${e}`, e)
95+
}
96+
})()
97+
}}
98+
>
99+
Copy to Clipboard
100+
</Button>
101+
<Button
102+
variant="contained"
103+
disabled={loading || !sequence}
104+
onClick={() => {
105+
try {
106+
const url = URL.createObjectURL(
107+
new Blob([sequence], { type: 'text/plain' }),
108+
)
109+
110+
// Create a temporary anchor element
111+
const a = document.createElement('a')
112+
a.href = url
113+
a.download = 'sequence.fasta'
114+
115+
// Trigger the download
116+
document.body.append(a)
117+
a.click()
118+
119+
// Clean up
120+
a.remove()
121+
URL.revokeObjectURL(url)
122+
getSession(model).notify('Sequence downloaded', 'info')
123+
} catch (e) {
124+
console.error(e)
125+
getSession(model).notifyError(`${e}`, e)
126+
}
127+
}}
128+
>
129+
Download
130+
</Button>
131+
</div>
132+
133+
{error ? (
134+
<ErrorMessage error={error} />
135+
) : (
136+
<>
137+
{loading ? <LoadingEllipses /> : null}
138+
<TextField
139+
variant="outlined"
140+
multiline
141+
minRows={5}
142+
maxRows={10}
143+
disabled={sequenceTooLarge}
144+
className={classes.dialogContent}
145+
fullWidth
146+
value={
147+
loading
148+
? 'Loading...'
149+
: sequenceTooLarge
150+
? 'Reference sequence too large to display, use the download FASTA button'
151+
: sequence
152+
}
153+
slotProps={{
154+
input: {
155+
readOnly: true,
156+
classes: {
157+
input: classes.textAreaInput,
158+
},
159+
},
160+
}}
161+
/>
162+
</>
163+
)}
164+
</DialogContent>
165+
<DialogActions>
166+
<Button color="primary" variant="outlined" onClick={onClose}>
167+
Close
168+
</Button>
169+
</DialogActions>
170+
</Dialog>
171+
)
172+
})
173+
174+
export default GetSequenceDialog

src/LinearMafDisplay/components/GetSequenceDialog/index.tsx

Lines changed: 0 additions & 159 deletions
This file was deleted.

0 commit comments

Comments
 (0)