@jbrowse/plugin-data-management 2.0.1 → 2.1.0
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/dist/AddTrackWidget/components/AddTrackWidget.d.ts +2 -2
- package/dist/AddTrackWidget/components/AddTrackWidget.js +18 -189
- package/dist/AddTrackWidget/components/AddTrackWidget.js.map +1 -1
- package/dist/AddTrackWidget/components/ConfirmTrack.js +5 -6
- package/dist/AddTrackWidget/components/ConfirmTrack.js.map +1 -1
- package/dist/AddTrackWidget/components/DefaultAddTrackWorkflow.d.ts +7 -0
- package/dist/AddTrackWidget/components/DefaultAddTrackWorkflow.js +222 -0
- package/dist/AddTrackWidget/components/DefaultAddTrackWorkflow.js.map +1 -0
- package/dist/HierarchicalTrackSelectorWidget/components/Header.d.ts +10 -0
- package/dist/HierarchicalTrackSelectorWidget/components/Header.js +209 -0
- package/dist/HierarchicalTrackSelectorWidget/components/Header.js.map +1 -0
- package/dist/HierarchicalTrackSelectorWidget/components/HierarchicalTrackSelector.js +22 -231
- package/dist/HierarchicalTrackSelectorWidget/components/HierarchicalTrackSelector.js.map +1 -1
- package/dist/HierarchicalTrackSelectorWidget/components/Node.d.ts +29 -0
- package/dist/HierarchicalTrackSelectorWidget/components/Node.js +207 -0
- package/dist/HierarchicalTrackSelectorWidget/components/Node.js.map +1 -0
- package/dist/HierarchicalTrackSelectorWidget/components/util.d.ts +3 -0
- package/dist/HierarchicalTrackSelectorWidget/components/util.js +11 -0
- package/dist/HierarchicalTrackSelectorWidget/components/util.js.map +1 -0
- package/dist/HierarchicalTrackSelectorWidget/configSchema.d.ts +2 -0
- package/dist/HierarchicalTrackSelectorWidget/configSchema.js +6 -0
- package/dist/HierarchicalTrackSelectorWidget/configSchema.js.map +1 -0
- package/dist/HierarchicalTrackSelectorWidget/index.d.ts +4 -2
- package/dist/HierarchicalTrackSelectorWidget/index.js +4 -4
- package/dist/HierarchicalTrackSelectorWidget/index.js.map +1 -1
- package/dist/HierarchicalTrackSelectorWidget/model.d.ts +10 -2
- package/dist/HierarchicalTrackSelectorWidget/model.js +35 -31
- package/dist/HierarchicalTrackSelectorWidget/model.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/esm/AddTrackWidget/components/AddTrackWidget.d.ts +2 -2
- package/esm/AddTrackWidget/components/AddTrackWidget.js +22 -135
- package/esm/AddTrackWidget/components/AddTrackWidget.js.map +1 -1
- package/esm/AddTrackWidget/components/ConfirmTrack.js +5 -6
- package/esm/AddTrackWidget/components/ConfirmTrack.js.map +1 -1
- package/esm/AddTrackWidget/components/DefaultAddTrackWorkflow.d.ts +7 -0
- package/esm/AddTrackWidget/components/DefaultAddTrackWorkflow.js +134 -0
- package/esm/AddTrackWidget/components/DefaultAddTrackWorkflow.js.map +1 -0
- package/esm/HierarchicalTrackSelectorWidget/components/Header.d.ts +10 -0
- package/esm/HierarchicalTrackSelectorWidget/components/Header.js +149 -0
- package/esm/HierarchicalTrackSelectorWidget/components/Header.js.map +1 -0
- package/esm/HierarchicalTrackSelectorWidget/components/HierarchicalTrackSelector.js +24 -223
- package/esm/HierarchicalTrackSelectorWidget/components/HierarchicalTrackSelector.js.map +1 -1
- package/esm/HierarchicalTrackSelectorWidget/components/Node.d.ts +29 -0
- package/esm/HierarchicalTrackSelectorWidget/components/Node.js +149 -0
- package/esm/HierarchicalTrackSelectorWidget/components/Node.js.map +1 -0
- package/esm/HierarchicalTrackSelectorWidget/components/util.d.ts +3 -0
- package/esm/HierarchicalTrackSelectorWidget/components/util.js +5 -0
- package/esm/HierarchicalTrackSelectorWidget/components/util.js.map +1 -0
- package/esm/HierarchicalTrackSelectorWidget/configSchema.d.ts +2 -0
- package/esm/HierarchicalTrackSelectorWidget/configSchema.js +4 -0
- package/esm/HierarchicalTrackSelectorWidget/configSchema.js.map +1 -0
- package/esm/HierarchicalTrackSelectorWidget/index.d.ts +4 -2
- package/esm/HierarchicalTrackSelectorWidget/index.js +3 -3
- package/esm/HierarchicalTrackSelectorWidget/index.js.map +1 -1
- package/esm/HierarchicalTrackSelectorWidget/model.d.ts +10 -2
- package/esm/HierarchicalTrackSelectorWidget/model.js +36 -32
- package/esm/HierarchicalTrackSelectorWidget/model.js.map +1 -1
- package/esm/index.d.ts +4 -1
- package/esm/index.js +1 -1
- package/esm/index.js.map +1 -1
- package/package.json +2 -2
- package/src/AddTrackWidget/components/{AddTrackWidget.test.js → AddTrackWidget.test.tsx} +17 -32
- package/src/AddTrackWidget/components/AddTrackWidget.tsx +36 -200
- package/src/AddTrackWidget/components/ConfirmTrack.tsx +10 -10
- package/src/AddTrackWidget/components/DefaultAddTrackWorkflow.tsx +205 -0
- package/src/HierarchicalTrackSelectorWidget/components/Header.tsx +287 -0
- package/src/HierarchicalTrackSelectorWidget/components/HierarchicalTrackSelector.tsx +19 -438
- package/src/HierarchicalTrackSelectorWidget/components/Node.tsx +284 -0
- package/src/HierarchicalTrackSelectorWidget/components/util.ts +11 -0
- package/src/HierarchicalTrackSelectorWidget/configSchema.ts +3 -0
- package/src/HierarchicalTrackSelectorWidget/index.ts +4 -6
- package/src/HierarchicalTrackSelectorWidget/model.ts +45 -41
- package/src/index.ts +4 -1
- package/src/AddTrackWidget/components/__snapshots__/AddTrackWidget.test.js.snap +0 -331
|
@@ -1,245 +1,47 @@
|
|
|
1
|
-
import React, {
|
|
2
|
-
|
|
3
|
-
lazy,
|
|
4
|
-
useCallback,
|
|
5
|
-
useMemo,
|
|
6
|
-
useState,
|
|
7
|
-
useRef,
|
|
8
|
-
useEffect,
|
|
9
|
-
} from 'react'
|
|
10
|
-
import {
|
|
11
|
-
Checkbox,
|
|
12
|
-
Fab,
|
|
13
|
-
FormControlLabel,
|
|
14
|
-
IconButton,
|
|
15
|
-
InputAdornment,
|
|
16
|
-
Menu,
|
|
17
|
-
MenuItem,
|
|
18
|
-
TextField,
|
|
19
|
-
Tooltip,
|
|
20
|
-
Typography,
|
|
21
|
-
} from '@mui/material'
|
|
1
|
+
import React, { useCallback, useMemo, useState, useRef, useEffect } from 'react'
|
|
2
|
+
import { Fab, Menu, MenuItem } from '@mui/material'
|
|
22
3
|
import { makeStyles } from 'tss-react/mui'
|
|
23
4
|
// icons
|
|
24
|
-
import ClearIcon from '@mui/icons-material/Clear'
|
|
25
5
|
import AddIcon from '@mui/icons-material/Add'
|
|
26
|
-
import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown'
|
|
27
|
-
import ArrowRightIcon from '@mui/icons-material/ArrowRight'
|
|
28
|
-
import MenuIcon from '@mui/icons-material/Menu'
|
|
29
|
-
import MoreIcon from '@mui/icons-material/MoreHoriz'
|
|
30
|
-
import { Cable } from '@jbrowse/core/ui/Icons'
|
|
31
|
-
|
|
32
6
|
// other
|
|
33
7
|
import AutoSizer from 'react-virtualized-auto-sizer'
|
|
34
|
-
import JBrowseMenu from '@jbrowse/core/ui/Menu'
|
|
35
8
|
import {
|
|
36
9
|
getSession,
|
|
37
10
|
isSessionModelWithWidgets,
|
|
38
11
|
isSessionModelWithConnections,
|
|
39
12
|
isSessionWithAddTracks,
|
|
40
13
|
} from '@jbrowse/core/util'
|
|
41
|
-
import {
|
|
42
|
-
AnyConfigurationModel,
|
|
43
|
-
readConfObject,
|
|
44
|
-
} from '@jbrowse/core/configuration'
|
|
45
14
|
import { observer } from 'mobx-react'
|
|
46
15
|
import { VariableSizeTree } from 'react-vtree'
|
|
47
16
|
|
|
48
17
|
// locals
|
|
49
18
|
import { TreeNode, HierarchicalTrackSelectorModel } from '../model'
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const CloseConnectionDialog = lazy(() => import('./CloseConnectionDialog'))
|
|
53
|
-
const DeleteConnectionDialog = lazy(() => import('./DeleteConnectionDialog'))
|
|
54
|
-
const ManageConnectionsDialog = lazy(() => import('./ManageConnectionsDialog'))
|
|
55
|
-
const ToggleConnectionsDialog = lazy(() => import('./ToggleConnectionsDialog'))
|
|
19
|
+
import Header from './Header'
|
|
20
|
+
import Node from './Node'
|
|
56
21
|
|
|
57
22
|
const useStyles = makeStyles()(theme => ({
|
|
58
|
-
searchBox: {
|
|
59
|
-
margin: theme.spacing(2),
|
|
60
|
-
},
|
|
61
|
-
menuIcon: {
|
|
62
|
-
marginRight: theme.spacing(1),
|
|
63
|
-
marginBottom: 0,
|
|
64
|
-
},
|
|
65
23
|
fab: {
|
|
66
24
|
position: 'absolute',
|
|
67
25
|
bottom: theme.spacing(6),
|
|
68
26
|
right: theme.spacing(6),
|
|
69
27
|
},
|
|
70
|
-
compactCheckbox: {
|
|
71
|
-
padding: 0,
|
|
72
|
-
},
|
|
73
|
-
|
|
74
|
-
checkboxLabel: {
|
|
75
|
-
marginRight: 0,
|
|
76
|
-
'&:hover': {
|
|
77
|
-
backgroundColor: '#eee',
|
|
78
|
-
},
|
|
79
|
-
},
|
|
80
|
-
|
|
81
|
-
// this accordionBase element's small padding is used to give a margin to
|
|
82
|
-
// accordionColor it a "margin" because the virtualized elements can't really
|
|
83
|
-
// use margin in a conventional way (it doesn't affect layout)
|
|
84
|
-
accordionBase: {
|
|
85
|
-
display: 'flex',
|
|
86
|
-
},
|
|
87
|
-
|
|
88
|
-
accordionCard: {
|
|
89
|
-
padding: 3,
|
|
90
|
-
cursor: 'pointer',
|
|
91
|
-
display: 'flex',
|
|
92
|
-
},
|
|
93
|
-
|
|
94
|
-
nestingLevelMarker: {
|
|
95
|
-
position: 'absolute',
|
|
96
|
-
borderLeft: '1.5px solid #555',
|
|
97
|
-
},
|
|
98
|
-
// accordionColor set's display:flex so that the child accordionText use
|
|
99
|
-
// vertically centered text
|
|
100
|
-
accordionColor: {
|
|
101
|
-
// @ts-ignore
|
|
102
|
-
background: theme.palette.tertiary?.main,
|
|
103
|
-
// @ts-ignore
|
|
104
|
-
color: theme.palette.tertiary?.contrastText,
|
|
105
|
-
width: '100%',
|
|
106
|
-
display: 'flex',
|
|
107
|
-
paddingLeft: 5,
|
|
108
|
-
},
|
|
109
|
-
|
|
110
|
-
// margin:auto 0 to center text vertically
|
|
111
|
-
accordionText: {
|
|
112
|
-
margin: 'auto 0',
|
|
113
|
-
},
|
|
114
28
|
}))
|
|
115
29
|
|
|
116
|
-
interface MoreInfoArgs {
|
|
117
|
-
target: HTMLElement
|
|
118
|
-
id: string
|
|
119
|
-
conf: AnyConfigurationModel
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// An individual node in the track selector. Note: manually sets cursor:
|
|
123
|
-
// pointer improves usability for what can be clicked
|
|
124
|
-
function Node(props: {
|
|
125
|
-
data: {
|
|
126
|
-
isLeaf: boolean
|
|
127
|
-
nestingLevel: number
|
|
128
|
-
checked: boolean
|
|
129
|
-
id: string
|
|
130
|
-
name: string
|
|
131
|
-
onChange: Function
|
|
132
|
-
toggleCollapse: (arg: string) => void
|
|
133
|
-
conf: AnyConfigurationModel
|
|
134
|
-
onMoreInfo: (arg: MoreInfoArgs) => void
|
|
135
|
-
drawerPosition: unknown
|
|
136
|
-
}
|
|
137
|
-
isOpen: boolean
|
|
138
|
-
style?: { height: number }
|
|
139
|
-
setOpen: (arg: boolean) => void
|
|
140
|
-
}) {
|
|
141
|
-
const { data, isOpen, style, setOpen } = props
|
|
142
|
-
const {
|
|
143
|
-
isLeaf,
|
|
144
|
-
nestingLevel,
|
|
145
|
-
checked,
|
|
146
|
-
id,
|
|
147
|
-
name,
|
|
148
|
-
onChange,
|
|
149
|
-
toggleCollapse,
|
|
150
|
-
conf,
|
|
151
|
-
onMoreInfo,
|
|
152
|
-
drawerPosition,
|
|
153
|
-
} = data
|
|
154
|
-
|
|
155
|
-
const { classes } = useStyles()
|
|
156
|
-
const width = 10
|
|
157
|
-
const marginLeft = nestingLevel * width + (isLeaf ? width : 0)
|
|
158
|
-
const unsupported =
|
|
159
|
-
name?.endsWith('(Unsupported)') || name?.endsWith('(Unknown)')
|
|
160
|
-
const description = (conf && readConfObject(conf, ['description'])) || ''
|
|
161
|
-
|
|
162
|
-
return (
|
|
163
|
-
<div style={style} className={!isLeaf ? classes.accordionBase : undefined}>
|
|
164
|
-
{new Array(nestingLevel).fill(0).map((_, idx) => (
|
|
165
|
-
<div
|
|
166
|
-
key={`mark-${idx}`}
|
|
167
|
-
style={{ left: idx * width + 4, height: style?.height }}
|
|
168
|
-
className={classes.nestingLevelMarker}
|
|
169
|
-
/>
|
|
170
|
-
))}
|
|
171
|
-
<div
|
|
172
|
-
className={!isLeaf ? classes.accordionCard : undefined}
|
|
173
|
-
onClick={() => {
|
|
174
|
-
toggleCollapse(id)
|
|
175
|
-
setOpen(!isOpen)
|
|
176
|
-
}}
|
|
177
|
-
style={{
|
|
178
|
-
marginLeft,
|
|
179
|
-
whiteSpace: 'nowrap',
|
|
180
|
-
width: '100%',
|
|
181
|
-
}}
|
|
182
|
-
>
|
|
183
|
-
<div className={!isLeaf ? classes.accordionColor : undefined}>
|
|
184
|
-
{!isLeaf ? (
|
|
185
|
-
<div className={classes.accordionText}>
|
|
186
|
-
<Typography>
|
|
187
|
-
{isOpen ? <ArrowDropDownIcon /> : <ArrowRightIcon />}
|
|
188
|
-
{name}
|
|
189
|
-
</Typography>
|
|
190
|
-
</div>
|
|
191
|
-
) : (
|
|
192
|
-
<>
|
|
193
|
-
<Tooltip
|
|
194
|
-
title={description}
|
|
195
|
-
placement={drawerPosition === 'left' ? 'right' : 'left'}
|
|
196
|
-
>
|
|
197
|
-
<FormControlLabel
|
|
198
|
-
className={classes.checkboxLabel}
|
|
199
|
-
control={
|
|
200
|
-
<Checkbox
|
|
201
|
-
className={classes.compactCheckbox}
|
|
202
|
-
checked={checked}
|
|
203
|
-
onChange={() => onChange(id)}
|
|
204
|
-
color="primary"
|
|
205
|
-
disabled={unsupported}
|
|
206
|
-
inputProps={{
|
|
207
|
-
// @ts-ignore
|
|
208
|
-
'data-testid': `htsTrackEntry-${id}`,
|
|
209
|
-
}}
|
|
210
|
-
/>
|
|
211
|
-
}
|
|
212
|
-
label={name}
|
|
213
|
-
/>
|
|
214
|
-
</Tooltip>
|
|
215
|
-
<IconButton
|
|
216
|
-
onClick={e => onMoreInfo({ target: e.currentTarget, id, conf })}
|
|
217
|
-
style={{ padding: 0 }}
|
|
218
|
-
color="secondary"
|
|
219
|
-
data-testid={`htsTrackEntryMenu-${id}`}
|
|
220
|
-
>
|
|
221
|
-
<MoreIcon />
|
|
222
|
-
</IconButton>
|
|
223
|
-
</>
|
|
224
|
-
)}
|
|
225
|
-
</div>
|
|
226
|
-
</div>
|
|
227
|
-
</div>
|
|
228
|
-
)
|
|
229
|
-
}
|
|
230
|
-
|
|
231
30
|
function getNodeData(
|
|
232
31
|
node: TreeNode,
|
|
233
32
|
nestingLevel: number,
|
|
234
33
|
extra: Record<string, unknown>,
|
|
34
|
+
selection: Record<string, unknown>,
|
|
235
35
|
) {
|
|
236
36
|
const isLeaf = !!node.conf
|
|
37
|
+
const selected = !!selection[node.id]
|
|
237
38
|
return {
|
|
238
39
|
data: {
|
|
239
40
|
defaultHeight: isLeaf ? 22 : 40,
|
|
240
41
|
isLeaf,
|
|
241
42
|
isOpenByDefault: true,
|
|
242
43
|
nestingLevel,
|
|
44
|
+
selected,
|
|
243
45
|
...node,
|
|
244
46
|
...extra,
|
|
245
47
|
},
|
|
@@ -263,26 +65,30 @@ const HierarchicalTree = observer(
|
|
|
263
65
|
tree: TreeNode
|
|
264
66
|
model: HierarchicalTrackSelectorModel
|
|
265
67
|
}) => {
|
|
266
|
-
const { filterText, view } = model
|
|
68
|
+
const { filterText, selection, view } = model
|
|
267
69
|
const treeRef = useRef<NodeData>(null)
|
|
268
|
-
const [info, setMoreInfo] = useState<MoreInfoArgs>()
|
|
269
70
|
const session = getSession(model)
|
|
270
71
|
const { drawerPosition } = session
|
|
72
|
+
const obj = useMemo(
|
|
73
|
+
() => Object.fromEntries(selection.map(s => [s.trackId, s])),
|
|
74
|
+
[selection],
|
|
75
|
+
)
|
|
271
76
|
|
|
272
77
|
const extra = useMemo(
|
|
273
78
|
() => ({
|
|
274
79
|
onChange: (trackId: string) => view.toggleTrack(trackId),
|
|
275
80
|
toggleCollapse: (pathName: string) => model.toggleCategory(pathName),
|
|
276
|
-
|
|
81
|
+
tree,
|
|
82
|
+
model,
|
|
277
83
|
drawerPosition,
|
|
278
84
|
}),
|
|
279
|
-
[view, model, drawerPosition],
|
|
85
|
+
[view, model, drawerPosition, tree],
|
|
280
86
|
)
|
|
281
87
|
const treeWalker = useCallback(
|
|
282
88
|
function* treeWalker() {
|
|
283
89
|
for (let i = 0; i < tree.children.length; i++) {
|
|
284
90
|
const r = tree.children[i]
|
|
285
|
-
yield getNodeData(r, 0, extra)
|
|
91
|
+
yield getNodeData(r, 0, extra, obj)
|
|
286
92
|
}
|
|
287
93
|
|
|
288
94
|
while (true) {
|
|
@@ -291,16 +97,13 @@ const HierarchicalTree = observer(
|
|
|
291
97
|
|
|
292
98
|
for (let i = 0; i < parentMeta.node.children.length; i++) {
|
|
293
99
|
const curr = parentMeta.node.children[i]
|
|
294
|
-
yield getNodeData(curr, parentMeta.nestingLevel + 1, extra)
|
|
100
|
+
yield getNodeData(curr, parentMeta.nestingLevel + 1, extra, obj)
|
|
295
101
|
}
|
|
296
102
|
}
|
|
297
103
|
},
|
|
298
|
-
[tree, extra],
|
|
104
|
+
[tree, extra, obj],
|
|
299
105
|
)
|
|
300
106
|
|
|
301
|
-
const conf = info?.conf
|
|
302
|
-
const menuItems = (conf && session.getTrackActionMenuItems?.(conf)) || []
|
|
303
|
-
|
|
304
107
|
useEffect(() => {
|
|
305
108
|
// @ts-ignore
|
|
306
109
|
treeRef.current.recomputeTree({
|
|
@@ -315,16 +118,6 @@ const HierarchicalTree = observer(
|
|
|
315
118
|
{/* @ts-ignore */}
|
|
316
119
|
{Node}
|
|
317
120
|
</VariableSizeTree>
|
|
318
|
-
<JBrowseMenu
|
|
319
|
-
anchorEl={info?.target}
|
|
320
|
-
menuItems={menuItems}
|
|
321
|
-
onMenuItemClick={(_event, callback) => {
|
|
322
|
-
callback()
|
|
323
|
-
setMoreInfo(undefined)
|
|
324
|
-
}}
|
|
325
|
-
open={Boolean(info)}
|
|
326
|
-
onClose={() => setMoreInfo(undefined)}
|
|
327
|
-
/>
|
|
328
121
|
</>
|
|
329
122
|
)
|
|
330
123
|
},
|
|
@@ -451,218 +244,6 @@ const HierarchicalTrackSelectorContainer = observer(
|
|
|
451
244
|
},
|
|
452
245
|
)
|
|
453
246
|
|
|
454
|
-
const HierarchicalTrackSelectorHeader = observer(
|
|
455
|
-
({
|
|
456
|
-
model,
|
|
457
|
-
setHeaderHeight,
|
|
458
|
-
setAssemblyIdx,
|
|
459
|
-
assemblyIdx,
|
|
460
|
-
}: {
|
|
461
|
-
model: HierarchicalTrackSelectorModel
|
|
462
|
-
setHeaderHeight: (n: number) => void
|
|
463
|
-
setAssemblyIdx: (n: number) => void
|
|
464
|
-
assemblyIdx: number
|
|
465
|
-
}) => {
|
|
466
|
-
const { classes } = useStyles()
|
|
467
|
-
const session = getSession(model)
|
|
468
|
-
const [connectionAnchorEl, setConnectionAnchorEl] =
|
|
469
|
-
useState<HTMLButtonElement>()
|
|
470
|
-
const [menuAnchorEl, setMenuAnchorEl] = useState<HTMLButtonElement>()
|
|
471
|
-
const [modalInfo, setModalInfo] = useState<{
|
|
472
|
-
connectionConf: AnyConfigurationModel
|
|
473
|
-
safelyBreakConnection: Function
|
|
474
|
-
dereferenceTypeCount: { [key: string]: number }
|
|
475
|
-
name: string
|
|
476
|
-
}>()
|
|
477
|
-
const [deleteDialogDetails, setDeleteDialogDetails] = useState<{
|
|
478
|
-
name: string
|
|
479
|
-
connectionConf: AnyConfigurationModel
|
|
480
|
-
}>()
|
|
481
|
-
const [connectionManagerOpen, setConnectionManagerOpen] = useState(false)
|
|
482
|
-
const [connectionToggleOpen, setConnectionToggleOpen] = useState(false)
|
|
483
|
-
const { assemblyNames } = model
|
|
484
|
-
const assemblyName = assemblyNames[assemblyIdx]
|
|
485
|
-
|
|
486
|
-
function breakConnection(
|
|
487
|
-
connectionConf: AnyConfigurationModel,
|
|
488
|
-
deletingConnection?: boolean,
|
|
489
|
-
) {
|
|
490
|
-
const name = readConfObject(connectionConf, 'name')
|
|
491
|
-
|
|
492
|
-
// @ts-ignore
|
|
493
|
-
const result = session.prepareToBreakConnection(connectionConf)
|
|
494
|
-
if (result) {
|
|
495
|
-
const [safelyBreakConnection, dereferenceTypeCount] = result
|
|
496
|
-
if (Object.keys(dereferenceTypeCount).length > 0) {
|
|
497
|
-
setModalInfo({
|
|
498
|
-
connectionConf,
|
|
499
|
-
safelyBreakConnection,
|
|
500
|
-
dereferenceTypeCount,
|
|
501
|
-
name,
|
|
502
|
-
})
|
|
503
|
-
} else {
|
|
504
|
-
safelyBreakConnection()
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
if (deletingConnection) {
|
|
508
|
-
setDeleteDialogDetails({ name, connectionConf })
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
const connectionMenuItems = [
|
|
513
|
-
{
|
|
514
|
-
label: 'Turn on/off connections...',
|
|
515
|
-
onClick: () => setConnectionToggleOpen(true),
|
|
516
|
-
},
|
|
517
|
-
]
|
|
518
|
-
|
|
519
|
-
if (isSessionModelWithConnections(session)) {
|
|
520
|
-
connectionMenuItems.unshift({
|
|
521
|
-
label: 'Add connection',
|
|
522
|
-
onClick: () => {
|
|
523
|
-
if (isSessionModelWithWidgets(session)) {
|
|
524
|
-
const widget = session.addWidget(
|
|
525
|
-
'AddConnectionWidget',
|
|
526
|
-
'addConnectionWidget',
|
|
527
|
-
)
|
|
528
|
-
session.showWidget(widget)
|
|
529
|
-
}
|
|
530
|
-
},
|
|
531
|
-
})
|
|
532
|
-
|
|
533
|
-
connectionMenuItems.push({
|
|
534
|
-
label: 'Delete connections...',
|
|
535
|
-
onClick: () => setConnectionManagerOpen(true),
|
|
536
|
-
})
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
const assemblyMenuItems =
|
|
540
|
-
assemblyNames.length > 1
|
|
541
|
-
? [
|
|
542
|
-
{
|
|
543
|
-
label: 'Select assembly...',
|
|
544
|
-
subMenu: assemblyNames.map((name, idx) => ({
|
|
545
|
-
label: name,
|
|
546
|
-
onClick: () => setAssemblyIdx(idx),
|
|
547
|
-
})),
|
|
548
|
-
},
|
|
549
|
-
]
|
|
550
|
-
: []
|
|
551
|
-
|
|
552
|
-
const menuItems = [
|
|
553
|
-
{
|
|
554
|
-
label: 'Add track...',
|
|
555
|
-
onClick: () => {
|
|
556
|
-
if (isSessionModelWithWidgets(session)) {
|
|
557
|
-
const widget = session.addWidget(
|
|
558
|
-
'AddTrackWidget',
|
|
559
|
-
'addTrackWidget',
|
|
560
|
-
{
|
|
561
|
-
view: model.view.id,
|
|
562
|
-
},
|
|
563
|
-
)
|
|
564
|
-
session.showWidget(widget)
|
|
565
|
-
}
|
|
566
|
-
},
|
|
567
|
-
},
|
|
568
|
-
|
|
569
|
-
...assemblyMenuItems,
|
|
570
|
-
]
|
|
571
|
-
|
|
572
|
-
return (
|
|
573
|
-
<div
|
|
574
|
-
ref={ref => setHeaderHeight(ref?.getBoundingClientRect().height || 0)}
|
|
575
|
-
data-testid="hierarchical_track_selector"
|
|
576
|
-
>
|
|
577
|
-
<div style={{ display: 'flex' }}>
|
|
578
|
-
{isSessionWithAddTracks(session) && (
|
|
579
|
-
<IconButton
|
|
580
|
-
className={classes.menuIcon}
|
|
581
|
-
onClick={event => setMenuAnchorEl(event.currentTarget)}
|
|
582
|
-
>
|
|
583
|
-
<MenuIcon />
|
|
584
|
-
</IconButton>
|
|
585
|
-
)}
|
|
586
|
-
|
|
587
|
-
{session.makeConnection && (
|
|
588
|
-
<IconButton
|
|
589
|
-
className={classes.menuIcon}
|
|
590
|
-
onClick={event => setConnectionAnchorEl(event.currentTarget)}
|
|
591
|
-
>
|
|
592
|
-
<Cable />
|
|
593
|
-
</IconButton>
|
|
594
|
-
)}
|
|
595
|
-
|
|
596
|
-
<TextField
|
|
597
|
-
className={classes.searchBox}
|
|
598
|
-
label="Filter tracks"
|
|
599
|
-
value={model.filterText}
|
|
600
|
-
onChange={event => model.setFilterText(event.target.value)}
|
|
601
|
-
fullWidth
|
|
602
|
-
InputProps={{
|
|
603
|
-
endAdornment: (
|
|
604
|
-
<InputAdornment position="end">
|
|
605
|
-
<IconButton color="secondary" onClick={model.clearFilterText}>
|
|
606
|
-
<ClearIcon />
|
|
607
|
-
</IconButton>
|
|
608
|
-
</InputAdornment>
|
|
609
|
-
),
|
|
610
|
-
}}
|
|
611
|
-
/>
|
|
612
|
-
</div>
|
|
613
|
-
<JBrowseMenu
|
|
614
|
-
anchorEl={connectionAnchorEl}
|
|
615
|
-
open={Boolean(connectionAnchorEl)}
|
|
616
|
-
onMenuItemClick={(_, callback) => {
|
|
617
|
-
callback()
|
|
618
|
-
setConnectionAnchorEl(undefined)
|
|
619
|
-
}}
|
|
620
|
-
onClose={() => setConnectionAnchorEl(undefined)}
|
|
621
|
-
menuItems={connectionMenuItems}
|
|
622
|
-
/>
|
|
623
|
-
<JBrowseMenu
|
|
624
|
-
anchorEl={menuAnchorEl}
|
|
625
|
-
open={Boolean(menuAnchorEl)}
|
|
626
|
-
onMenuItemClick={(_, callback) => {
|
|
627
|
-
callback()
|
|
628
|
-
setMenuAnchorEl(undefined)
|
|
629
|
-
}}
|
|
630
|
-
onClose={() => setMenuAnchorEl(undefined)}
|
|
631
|
-
menuItems={menuItems}
|
|
632
|
-
/>
|
|
633
|
-
<Suspense fallback={<div />}>
|
|
634
|
-
{modalInfo ? (
|
|
635
|
-
<CloseConnectionDialog
|
|
636
|
-
modalInfo={modalInfo}
|
|
637
|
-
setModalInfo={setModalInfo}
|
|
638
|
-
/>
|
|
639
|
-
) : deleteDialogDetails ? (
|
|
640
|
-
<DeleteConnectionDialog
|
|
641
|
-
handleClose={() => setDeleteDialogDetails(undefined)}
|
|
642
|
-
deleteDialogDetails={deleteDialogDetails}
|
|
643
|
-
session={session}
|
|
644
|
-
/>
|
|
645
|
-
) : null}
|
|
646
|
-
{connectionManagerOpen ? (
|
|
647
|
-
<ManageConnectionsDialog
|
|
648
|
-
handleClose={() => setConnectionManagerOpen(false)}
|
|
649
|
-
breakConnection={breakConnection}
|
|
650
|
-
session={session}
|
|
651
|
-
/>
|
|
652
|
-
) : null}
|
|
653
|
-
{connectionToggleOpen ? (
|
|
654
|
-
<ToggleConnectionsDialog
|
|
655
|
-
handleClose={() => setConnectionToggleOpen(false)}
|
|
656
|
-
session={session}
|
|
657
|
-
breakConnection={breakConnection}
|
|
658
|
-
assemblyName={assemblyName}
|
|
659
|
-
/>
|
|
660
|
-
) : null}
|
|
661
|
-
</Suspense>
|
|
662
|
-
</div>
|
|
663
|
-
)
|
|
664
|
-
},
|
|
665
|
-
)
|
|
666
247
|
const HierarchicalTrackSelector = observer(
|
|
667
248
|
({
|
|
668
249
|
model,
|
|
@@ -678,7 +259,7 @@ const HierarchicalTrackSelector = observer(
|
|
|
678
259
|
const assemblyName = assemblyNames[assemblyIdx]
|
|
679
260
|
return assemblyName ? (
|
|
680
261
|
<>
|
|
681
|
-
<
|
|
262
|
+
<Header
|
|
682
263
|
model={model}
|
|
683
264
|
setHeaderHeight={setHeaderHeight}
|
|
684
265
|
setAssemblyIdx={setAssemblyIdx}
|