@jbrowse/plugin-data-management 1.4.1 → 1.5.2

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 (37) hide show
  1. package/dist/AddTrackWidget/components/TrackSourceSelect.d.ts +2 -1
  2. package/dist/AddTrackWidget/model.d.ts +1 -363
  3. package/dist/PluginStoreWidget/components/CustomPluginForm.d.ts +1 -1
  4. package/dist/PluginStoreWidget/components/PluginCard.d.ts +2 -2
  5. package/dist/SetDefaultSession/SetDefaultSession.d.ts +4 -6
  6. package/dist/index.d.ts +8 -12
  7. package/dist/plugin-data-management.cjs.development.js +627 -501
  8. package/dist/plugin-data-management.cjs.development.js.map +1 -1
  9. package/dist/plugin-data-management.cjs.production.min.js +1 -1
  10. package/dist/plugin-data-management.cjs.production.min.js.map +1 -1
  11. package/dist/plugin-data-management.esm.js +614 -507
  12. package/dist/plugin-data-management.esm.js.map +1 -1
  13. package/package.json +3 -2
  14. package/src/AddConnectionWidget/components/AddConnectionWidget.test.js +3 -8
  15. package/src/AddTrackWidget/components/AddTrackWidget.test.js +2 -3
  16. package/src/AddTrackWidget/components/AddTrackWidget.tsx +4 -2
  17. package/src/AddTrackWidget/components/ConfirmTrack.tsx +160 -88
  18. package/src/AddTrackWidget/components/TrackSourceSelect.tsx +30 -23
  19. package/src/AddTrackWidget/components/__snapshots__/AddTrackWidget.test.js.snap +157 -124
  20. package/src/AddTrackWidget/index.test.jsx +78 -26
  21. package/src/AddTrackWidget/model.ts +5 -14
  22. package/src/AssemblyManager/AssemblyAddForm.tsx +7 -6
  23. package/src/AssemblyManager/AssemblyManager.test.tsx +1 -0
  24. package/src/HierarchicalTrackSelectorWidget/components/HierarchicalTrackSelector.js +27 -17
  25. package/src/HierarchicalTrackSelectorWidget/model.js +3 -2
  26. package/src/PluginStoreWidget/components/CustomPluginForm.tsx +164 -56
  27. package/src/PluginStoreWidget/components/InstalledPlugin.tsx +10 -2
  28. package/src/PluginStoreWidget/components/PluginCard.tsx +7 -9
  29. package/src/PluginStoreWidget/components/PluginStoreWidget.test.js +9 -10
  30. package/src/PluginStoreWidget/components/PluginStoreWidget.tsx +36 -26
  31. package/src/PluginStoreWidget/components/__snapshots__/PluginStoreWidget.test.js.snap +89 -51
  32. package/src/SetDefaultSession/SetDefaultSession.test.tsx +7 -81
  33. package/src/SetDefaultSession/SetDefaultSession.tsx +51 -162
  34. package/src/index.ts +1 -51
  35. package/src/ucsc-trackhub/configSchema.js +4 -1
  36. package/src/ucsc-trackhub/model.js +31 -31
  37. package/src/ucsc-trackhub/ucscTrackHub.js +40 -12
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jbrowse/plugin-data-management",
3
- "version": "1.4.1",
3
+ "version": "1.5.2",
4
4
  "description": "JBrowse 2 linear genome view",
5
5
  "keywords": [
6
6
  "jbrowse",
@@ -37,6 +37,7 @@
37
37
  "dependencies": {
38
38
  "@gmod/ucsc-hub": "^0.1.3",
39
39
  "@material-ui/icons": "^4.9.1",
40
+ "clsx": "^1.1.0",
40
41
  "pluralize": "^8.0.0",
41
42
  "react-virtualized-auto-sizer": "^1.0.2",
42
43
  "react-vtree": "^3.0.0-beta.1",
@@ -55,5 +56,5 @@
55
56
  "publishConfig": {
56
57
  "access": "public"
57
58
  },
58
- "gitHead": "42c7e1b98bb0d16fa440a8a8f500a1030607f16c"
59
+ "gitHead": "94fdfbc34787ab8f12a87e00038da74b247b42fa"
59
60
  }
@@ -24,8 +24,7 @@ describe('<AddConnectionWidget />', () => {
24
24
  uniqueId: 'firstId',
25
25
  start: 0,
26
26
  end: 1000,
27
- seq:
28
- 'cattgttgcggagttgaacaACGGCATTAGGAACACTTCCGTCTCtcacttttatacgattatgattggttctttagccttggtttagattggtagtagtagcggcgctaatgctacctgaattgagaactcgagcgggggctaggcaaattctgattcagcctgacttctcttggaaccctgcccataaatcaaagggttagtgcggccaaaacgttggacaacggtattagaagaccaacctgaccaccaaaccgtcaattaaccggtatcttctcggaaacggcggttctctcctagatagcgatctgtggtctcaccatgcaatttaaacaggtgagtaaagattgctacaaatacgagactagctgtcaccagatgctgttcatctgttggctccttggtcgctccgttgtacccaggctactttgaaagagcgcagaatacttagacggtatcgatcatggtagcatagcattctgataacatgtatggagttcgaacatccgtctggggccggacggtccgtttgaggttggttgatctgggtgatagtcagcaagatagacgttagataacaaattaaaggattttaccttagattgcgactagtacaacggtacatcggtgattcgcgctctactagatcacgctatgggtaccataaacaaacggtggaccttctcaagctggttgacgcctcagcaacataggcttcctcctccacgcatctcagcataaaaggcttataaactgcttctttgtgccagagcaactcaattaagcccttggtaccgtgggcacgcattctgtcacggtgaccaactgttcatcctgaatcgccgaatgggactatttggtacaggaatcaagcggatggcactactgcagcttatttacgacggtattcttaaagtttttaagacaatgtatttcatgggtagttcggtttgttttattgctacacaggctcttgtagacgacctacttagcactacgg',
27
+ seq: 'cattgttgcggagttgaacaACGGCATTAGGAACACTTCCGTCTCtcacttttatacgattatgattggttctttagccttggtttagattggtagtagtagcggcgctaatgctacctgaattgagaactcgagcgggggctaggcaaattctgattcagcctgacttctcttggaaccctgcccataaatcaaagggttagtgcggccaaaacgttggacaacggtattagaagaccaacctgaccaccaaaccgtcaattaaccggtatcttctcggaaacggcggttctctcctagatagcgatctgtggtctcaccatgcaatttaaacaggtgagtaaagattgctacaaatacgagactagctgtcaccagatgctgttcatctgttggctccttggtcgctccgttgtacccaggctactttgaaagagcgcagaatacttagacggtatcgatcatggtagcatagcattctgataacatgtatggagttcgaacatccgtctggggccggacggtccgtttgaggttggttgatctgggtgatagtcagcaagatagacgttagataacaaattaaaggattttaccttagattgcgactagtacaacggtacatcggtgattcgcgctctactagatcacgctatgggtaccataaacaaacggtggaccttctcaagctggttgacgcctcagcaacataggcttcctcctccacgcatctcagcataaaaggcttataaactgcttctttgtgccagagcaactcaattaagcccttggtaccgtgggcacgcattctgtcacggtgaccaactgttcatcctgaatcgccgaatgggactatttggtacaggaatcaagcggatggcactactgcagcttatttacgacggtattcttaaagtttttaagacaatgtatttcatgggtagttcggtttgttttattgctacacaggctcttgtagacgacctacttagcactacgg',
29
28
  },
30
29
  ],
31
30
  },
@@ -69,12 +68,8 @@ type bigWig
69
68
  return Promise.resolve(new Response(responseText, { url: urlText }))
70
69
  }
71
70
  jest.spyOn(global, 'fetch').mockImplementation(mockFetch)
72
- const {
73
- findByTestId,
74
- getAllByRole,
75
- findAllByText,
76
- findByDisplayValue,
77
- } = render(<AddConnectionWidget model={model} />)
71
+ const { findByTestId, getAllByRole, findAllByText, findByDisplayValue } =
72
+ render(<AddConnectionWidget model={model} />)
78
73
  expect(session.connections.length).toBe(0)
79
74
  fireEvent.mouseDown(getAllByRole('button')[0])
80
75
  const ucscTrackHubSelection = await findAllByText('UCSC Track Hub')
@@ -22,8 +22,7 @@ describe('<AddTrackWidget />', () => {
22
22
  uniqueId: 'firstId',
23
23
  start: 0,
24
24
  end: 1000,
25
- seq:
26
- 'cattgttgcggagttgaacaACGGCATTAGGAACACTTCCGTCTCtcacttttatacgattatgattggttctttagccttggtttagattggtagtagtagcggcgctaatgctacctgaattgagaactcgagcgggggctaggcaaattctgattcagcctgacttctcttggaaccctgcccataaatcaaagggttagtgcggccaaaacgttggacaacggtattagaagaccaacctgaccaccaaaccgtcaattaaccggtatcttctcggaaacggcggttctctcctagatagcgatctgtggtctcaccatgcaatttaaacaggtgagtaaagattgctacaaatacgagactagctgtcaccagatgctgttcatctgttggctccttggtcgctccgttgtacccaggctactttgaaagagcgcagaatacttagacggtatcgatcatggtagcatagcattctgataacatgtatggagttcgaacatccgtctggggccggacggtccgtttgaggttggttgatctgggtgatagtcagcaagatagacgttagataacaaattaaaggattttaccttagattgcgactagtacaacggtacatcggtgattcgcgctctactagatcacgctatgggtaccataaacaaacggtggaccttctcaagctggttgacgcctcagcaacataggcttcctcctccacgcatctcagcataaaaggcttataaactgcttctttgtgccagagcaactcaattaagcccttggtaccgtgggcacgcattctgtcacggtgaccaactgttcatcctgaatcgccgaatgggactatttggtacaggaatcaagcggatggcactactgcagcttatttacgacggtattcttaaagtttttaagacaatgtatttcatgggtagttcggtttgttttattgctacacaggctcttgtagacgacctacttagcactacgg',
25
+ seq: 'cattgttgcggagttgaacaACGGCATTAGGAACACTTCCGTCTCtcacttttatacgattatgattggttctttagccttggtttagattggtagtagtagcggcgctaatgctacctgaattgagaactcgagcgggggctaggcaaattctgattcagcctgacttctcttggaaccctgcccataaatcaaagggttagtgcggccaaaacgttggacaacggtattagaagaccaacctgaccaccaaaccgtcaattaaccggtatcttctcggaaacggcggttctctcctagatagcgatctgtggtctcaccatgcaatttaaacaggtgagtaaagattgctacaaatacgagactagctgtcaccagatgctgttcatctgttggctccttggtcgctccgttgtacccaggctactttgaaagagcgcagaatacttagacggtatcgatcatggtagcatagcattctgataacatgtatggagttcgaacatccgtctggggccggacggtccgtttgaggttggttgatctgggtgatagtcagcaagatagacgttagataacaaattaaaggattttaccttagattgcgactagtacaacggtacatcggtgattcgcgctctactagatcacgctatgggtaccataaacaaacggtggaccttctcaagctggttgacgcctcagcaacataggcttcctcctccacgcatctcagcataaaaggcttataaactgcttctttgtgccagagcaactcaattaagcccttggtaccgtgggcacgcattctgtcacggtgaccaactgttcatcctgaatcgccgaatgggactatttggtacaggaatcaagcggatggcactactgcagcttatttacgacggtattcttaaagtttttaagacaatgtatttcatgggtagttcggtttgttttattgctacacaggctcttgtagacgacctacttagcactacgg',
27
26
  },
28
27
  ],
29
28
  },
@@ -126,7 +125,7 @@ describe('<AddTrackWidget />', () => {
126
125
  expect(session.sessionTracks.length).toBe(2)
127
126
  })
128
127
 
129
- it('fails to add a track', async () => {
128
+ xit('fails to add a track', async () => {
130
129
  const { getByTestId, getAllByTestId, findByText } = render(
131
130
  <AddTrackWidget model={model} />,
132
131
  )
@@ -11,10 +11,12 @@ import {
11
11
  import { getSession } from '@jbrowse/core/util'
12
12
  import { getConf } from '@jbrowse/core/configuration'
13
13
  import { observer } from 'mobx-react'
14
+ import { Alert } from '@material-ui/lab'
15
+
16
+ // locals
14
17
  import ConfirmTrack from './ConfirmTrack'
15
18
  import TrackSourceSelect from './TrackSourceSelect'
16
19
  import { AddTrackModel } from '../model'
17
- import { Alert } from '@material-ui/lab'
18
20
 
19
21
  const useStyles = makeStyles(theme => ({
20
22
  root: {
@@ -58,7 +60,7 @@ function AddTrackWidget({ model }: { model: AddTrackModel }) {
58
60
  }
59
61
  }
60
62
 
61
- function handleNext() {
63
+ async function handleNext() {
62
64
  if (activeStep !== steps.length - 1) {
63
65
  setActiveStep(activeStep + 1)
64
66
  return
@@ -1,15 +1,22 @@
1
+ import React from 'react'
1
2
  import { readConfObject } from '@jbrowse/core/configuration'
2
3
  import { getSession } from '@jbrowse/core/util'
3
- import Link from '@material-ui/core/Link'
4
- import MenuItem from '@material-ui/core/MenuItem'
5
- import { makeStyles } from '@material-ui/core/styles'
6
- import TextField from '@material-ui/core/TextField'
7
- import Typography from '@material-ui/core/Typography'
4
+ import {
5
+ Link,
6
+ MenuItem,
7
+ TextField,
8
+ ListSubheader,
9
+ Typography,
10
+ makeStyles,
11
+ } from '@material-ui/core'
12
+ import PluginManager from '@jbrowse/core/PluginManager'
8
13
  import { observer } from 'mobx-react'
9
14
  import { getEnv } from 'mobx-state-tree'
10
- import React from 'react'
11
15
  import { UNKNOWN } from '@jbrowse/core/util/tracks'
16
+
17
+ // locals
12
18
  import { AddTrackModel } from '../model'
19
+ import { AdapterMetadata } from '@jbrowse/core/pluggableElementTypes/AdapterType'
13
20
 
14
21
  const useStyles = makeStyles(theme => ({
15
22
  spacing: {
@@ -41,52 +48,105 @@ function StatusMessage({
41
48
  )
42
49
  }
43
50
 
44
- function TrackAdapterSelector({
45
- adapterHint,
46
- model,
47
- }: {
48
- adapterHint: string
49
- model: AddTrackModel
50
- }) {
51
+ /**
52
+ * categorizeAdapters takes a list of adapters and sorts their menu item elements under an appropriate ListSubheader
53
+ * element. In this way, adapters that are from external plugins can have headers that differentiate them from the
54
+ * out-of-the-box plugins.
55
+ * @param adaptersList - a list of adapters found in the PluginManager
56
+ * @returns a series of JSX elements that are ListSubheaders followed by the adapters
57
+ * found under that subheader
58
+ */
59
+ function categorizeAdapters(
60
+ adaptersList: { name: string; adapterMetadata: AdapterMetadata }[],
61
+ ) {
62
+ let currentCategory = ''
63
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
64
+ const items: any = []
65
+ adaptersList.forEach(adapter => {
66
+ if (adapter.adapterMetadata?.category) {
67
+ if (currentCategory !== adapter.adapterMetadata?.category) {
68
+ currentCategory = adapter.adapterMetadata?.category
69
+ items.push(
70
+ <ListSubheader
71
+ key={adapter.adapterMetadata?.category}
72
+ value={adapter.adapterMetadata?.category}
73
+ >
74
+ {adapter.adapterMetadata?.category}
75
+ </ListSubheader>,
76
+ )
77
+ }
78
+ items.push(
79
+ <MenuItem key={adapter.name} value={adapter.name}>
80
+ {adapter.adapterMetadata?.displayName
81
+ ? adapter.adapterMetadata?.displayName
82
+ : adapter.name}
83
+ </MenuItem>,
84
+ )
85
+ }
86
+ })
87
+ return items
88
+ }
89
+
90
+ function getAdapterTypes(pluginManager: PluginManager) {
91
+ return pluginManager.getElementTypesInGroup('adapter') as {
92
+ name: string
93
+ adapterMetadata: AdapterMetadata
94
+ }[]
95
+ }
96
+
97
+ function getTrackTypes(pluginManager: PluginManager) {
98
+ return pluginManager.getElementTypesInGroup('track') as { name: string }[]
99
+ }
100
+
101
+ const TrackAdapterSelector = observer(({ model }: { model: AddTrackModel }) => {
51
102
  const classes = useStyles()
52
103
  const session = getSession(model)
104
+ const { trackAdapter } = model
105
+ // prettier-ignore
106
+ const adapters = getAdapterTypes(getEnv(session).pluginManager)
53
107
  return (
54
108
  <TextField
55
109
  className={classes.spacing}
56
- value={adapterHint}
110
+ value={trackAdapter?.type !== 'UNKNOWN' ? trackAdapter?.type : ''}
57
111
  label="adapterType"
58
- helperText="An adapter type"
112
+ helperText="Select an adapter type"
59
113
  select
60
114
  fullWidth
61
- onChange={event => {
62
- model.setAdapterHint(event.target.value)
63
- }}
115
+ onChange={event => model.setAdapterHint(event.target.value)}
64
116
  SelectProps={{
65
117
  // @ts-ignore
66
118
  SelectDisplayProps: { 'data-testid': 'adapterTypeSelect' },
67
119
  }}
68
120
  >
69
- {getEnv(session)
70
- .pluginManager.getElementTypesInGroup('adapter')
71
- // Exclude SNPCoverageAdapter from primary adapter user selection
72
- .filter((elt: { name: string }) => elt.name !== 'SNPCoverageAdapter')
73
- .map((elt: { name: string }) => (
121
+ {adapters
122
+ // Excludes any adapter with the 'adapterMetadata.hiddenFromGUI' property, and anything with the 'adapterMetadata.category' property
123
+ .filter(
124
+ elt =>
125
+ !elt.adapterMetadata?.hiddenFromGUI &&
126
+ !elt.adapterMetadata?.category,
127
+ )
128
+ .map(elt => (
74
129
  <MenuItem key={elt.name} value={elt.name}>
75
- {elt.name}
130
+ {elt.adapterMetadata?.displayName
131
+ ? elt.adapterMetadata?.displayName
132
+ : elt.name}
76
133
  </MenuItem>
77
134
  ))}
135
+ {/* adapters with the 'adapterMetadata.category' property are categorized by the value of the property here */}
136
+ {categorizeAdapters(
137
+ adapters.filter(elt => !elt.adapterMetadata?.hiddenFromGUI),
138
+ )}
78
139
  </TextField>
79
140
  )
80
- }
141
+ })
81
142
 
82
143
  function UnknownAdapterPrompt({ model }: { model: AddTrackModel }) {
83
144
  const classes = useStyles()
84
- const { adapterHint } = model
85
145
  return (
86
146
  <>
87
147
  <Typography className={classes.spacing}>
88
- Was not able to guess the adapter type for this data, but it may be in
89
- the list below. If not, you can{' '}
148
+ JBrowse was not able to guess the adapter type for this data, but it may
149
+ be in the list below. If not, you can{' '}
90
150
  <Link
91
151
  href="https://github.com/GMOD/jbrowse-components/releases"
92
152
  target="_blank"
@@ -104,22 +164,75 @@ function UnknownAdapterPrompt({ model }: { model: AddTrackModel }) {
104
164
  </Link>{' '}
105
165
  and add a feature request for this data type.
106
166
  </Typography>
107
- <TrackAdapterSelector adapterHint={adapterHint} model={model} />
167
+ <TrackAdapterSelector model={model} />
108
168
  </>
109
169
  )
110
170
  }
111
171
 
112
- function ConfirmTrack({ model }: { model: AddTrackModel }) {
172
+ const TrackTypeSelector = observer(({ model }: { model: AddTrackModel }) => {
113
173
  const classes = useStyles()
114
174
  const session = getSession(model)
115
- const {
116
- trackName,
117
- trackAdapter,
118
- trackType,
119
- assembly,
120
- warningMessage,
121
- adapterHint,
122
- } = model
175
+ const { trackType } = model
176
+ const trackTypes = getTrackTypes(getEnv(session).pluginManager)
177
+
178
+ return (
179
+ <TextField
180
+ className={classes.spacing}
181
+ value={trackType}
182
+ label="trackType"
183
+ helperText="Select a track type"
184
+ select
185
+ fullWidth
186
+ onChange={event => {
187
+ model.setTrackType(event.target.value)
188
+ }}
189
+ SelectProps={{
190
+ // @ts-ignore
191
+ SelectDisplayProps: { 'data-testid': 'trackTypeSelect' },
192
+ }}
193
+ >
194
+ {trackTypes.map(({ name }) => (
195
+ <MenuItem key={name} value={name}>
196
+ {name}
197
+ </MenuItem>
198
+ ))}
199
+ </TextField>
200
+ )
201
+ })
202
+
203
+ const TrackAssemblySelector = observer(
204
+ ({ model }: { model: AddTrackModel }) => {
205
+ const session = getSession(model)
206
+ const { assembly } = model
207
+ return (
208
+ <TextField
209
+ value={assembly}
210
+ label="assemblyName"
211
+ helperText="Assembly to which the track will be added"
212
+ select
213
+ fullWidth
214
+ onChange={event => model.setAssembly(event.target.value)}
215
+ SelectProps={{
216
+ // @ts-ignore
217
+ SelectDisplayProps: { 'data-testid': 'assemblyNameSelect' },
218
+ }}
219
+ >
220
+ {session.assemblies
221
+ .map(conf => readConfObject(conf, 'name'))
222
+ .map(name => (
223
+ <MenuItem key={name} value={name}>
224
+ {name}
225
+ </MenuItem>
226
+ ))}
227
+ </TextField>
228
+ )
229
+ },
230
+ )
231
+
232
+ function ConfirmTrack({ model }: { model: AddTrackModel }) {
233
+ const classes = useStyles()
234
+ const { trackName, trackAdapter, trackType, warningMessage, adapterHint } =
235
+ model
123
236
 
124
237
  if (model.unsupported) {
125
238
  return (
@@ -150,19 +263,22 @@ function ConfirmTrack({ model }: { model: AddTrackModel }) {
150
263
  return <UnknownAdapterPrompt model={model} />
151
264
  }
152
265
 
266
+ if (adapterHint === '' && trackAdapter) {
267
+ model.setAdapterHint(trackAdapter.type)
268
+ }
269
+
153
270
  if (!trackAdapter?.type) {
154
271
  return <Typography>Could not recognize this data type.</Typography>
155
272
  }
156
273
 
157
274
  return (
158
- <>
275
+ <div>
159
276
  {trackAdapter ? (
160
277
  <StatusMessage trackAdapter={trackAdapter} trackType={trackType} />
161
278
  ) : null}
162
279
  {warningMessage ? (
163
280
  <Typography style={{ color: 'orange' }}>{warningMessage}</Typography>
164
281
  ) : null}
165
- <TrackAdapterSelector adapterHint={adapterHint} model={model} />
166
282
  <TextField
167
283
  className={classes.spacing}
168
284
  label="trackName"
@@ -172,54 +288,10 @@ function ConfirmTrack({ model }: { model: AddTrackModel }) {
172
288
  onChange={event => model.setTrackName(event.target.value)}
173
289
  inputProps={{ 'data-testid': 'trackNameInput' }}
174
290
  />
175
- <TextField
176
- className={classes.spacing}
177
- value={trackType}
178
- label="trackType"
179
- helperText="A track type"
180
- select
181
- fullWidth
182
- onChange={event => {
183
- model.setTrackType(event.target.value)
184
- }}
185
- SelectProps={{
186
- // @ts-ignore
187
- SelectDisplayProps: { 'data-testid': 'trackTypeSelect' },
188
- }}
189
- >
190
- {getEnv(session)
191
- .pluginManager.getElementTypesInGroup('track')
192
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
193
- .map(({ name }: any) => (
194
- <MenuItem key={name} value={name}>
195
- {name}
196
- </MenuItem>
197
- ))}
198
- </TextField>
199
- <TextField
200
- value={assembly}
201
- label="assemblyName"
202
- helperText="Assembly to which the track will be added"
203
- select
204
- fullWidth
205
- onChange={event => {
206
- model.setAssembly(event.target.value)
207
- }}
208
- SelectProps={{
209
- // @ts-ignore
210
- SelectDisplayProps: { 'data-testid': 'assemblyNameSelect' },
211
- }}
212
- >
213
- {session.assemblies.map(assemblyConf => {
214
- const assemblyName = readConfObject(assemblyConf, 'name')
215
- return (
216
- <MenuItem key={assemblyName} value={assemblyName}>
217
- {assemblyName}
218
- </MenuItem>
219
- )
220
- })}
221
- </TextField>
222
- </>
291
+ <TrackAdapterSelector model={model} />
292
+ <TrackTypeSelector model={model} />
293
+ <TrackAssemblySelector model={model} />
294
+ </div>
223
295
  )
224
296
  }
225
297
 
@@ -1,39 +1,46 @@
1
- import { FileSelector } from '@jbrowse/core/ui'
2
- import Paper from '@material-ui/core/Paper'
3
- import { makeStyles } from '@material-ui/core/styles'
4
1
  import React from 'react'
2
+ import { FileSelector } from '@jbrowse/core/ui'
3
+ import { Paper, makeStyles } from '@material-ui/core'
5
4
  import { AddTrackModel } from '../model'
5
+ import { getRoot } from 'mobx-state-tree'
6
+ import { observer } from 'mobx-react'
6
7
 
7
8
  const useStyles = makeStyles(theme => ({
8
- root: {
9
+ paper: {
9
10
  display: 'flex',
10
11
  flexDirection: 'column',
11
- },
12
- paper: {
13
12
  padding: theme.spacing(1),
14
13
  },
14
+ spacer: {
15
+ height: theme.spacing(8),
16
+ },
15
17
  }))
16
18
 
17
19
  function TrackSourceSelect({ model }: { model: AddTrackModel }) {
18
20
  const classes = useStyles()
21
+ const rootModel = getRoot(model)
22
+
19
23
  return (
20
- <div className={classes.root}>
21
- <Paper className={classes.paper}>
22
- <FileSelector
23
- name="Main file"
24
- description=""
25
- location={model.trackData}
26
- setLocation={model.setTrackData}
27
- />
28
- <FileSelector
29
- name="Index file"
30
- description="Automatically inferred from the URL if not supplied"
31
- location={model.indexTrackData}
32
- setLocation={model.setIndexTrackData}
33
- />
34
- </Paper>
35
- </div>
24
+ <Paper className={classes.paper}>
25
+ <FileSelector
26
+ name="Main file"
27
+ description=""
28
+ location={model.trackData}
29
+ setLocation={model.setTrackData}
30
+ setName={model.setTrackName}
31
+ rootModel={rootModel}
32
+ />
33
+ <div className={classes.spacer} />
34
+ <FileSelector
35
+ name="Index file"
36
+ description="(Optional) The URL of the index file is automatically inferred from the URL of the main file if it is not supplied."
37
+ location={model.indexTrackData}
38
+ setLocation={model.setIndexTrackData}
39
+ setName={model.setTrackName}
40
+ rootModel={rootModel}
41
+ />
42
+ </Paper>
36
43
  )
37
44
  }
38
45
 
39
- export default TrackSourceSelect
46
+ export default observer(TrackSourceSelect)