@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.
Files changed (76) hide show
  1. package/dist/AddTrackWidget/components/AddTrackWidget.d.ts +2 -2
  2. package/dist/AddTrackWidget/components/AddTrackWidget.js +18 -189
  3. package/dist/AddTrackWidget/components/AddTrackWidget.js.map +1 -1
  4. package/dist/AddTrackWidget/components/ConfirmTrack.js +5 -6
  5. package/dist/AddTrackWidget/components/ConfirmTrack.js.map +1 -1
  6. package/dist/AddTrackWidget/components/DefaultAddTrackWorkflow.d.ts +7 -0
  7. package/dist/AddTrackWidget/components/DefaultAddTrackWorkflow.js +222 -0
  8. package/dist/AddTrackWidget/components/DefaultAddTrackWorkflow.js.map +1 -0
  9. package/dist/HierarchicalTrackSelectorWidget/components/Header.d.ts +10 -0
  10. package/dist/HierarchicalTrackSelectorWidget/components/Header.js +209 -0
  11. package/dist/HierarchicalTrackSelectorWidget/components/Header.js.map +1 -0
  12. package/dist/HierarchicalTrackSelectorWidget/components/HierarchicalTrackSelector.js +22 -231
  13. package/dist/HierarchicalTrackSelectorWidget/components/HierarchicalTrackSelector.js.map +1 -1
  14. package/dist/HierarchicalTrackSelectorWidget/components/Node.d.ts +29 -0
  15. package/dist/HierarchicalTrackSelectorWidget/components/Node.js +207 -0
  16. package/dist/HierarchicalTrackSelectorWidget/components/Node.js.map +1 -0
  17. package/dist/HierarchicalTrackSelectorWidget/components/util.d.ts +3 -0
  18. package/dist/HierarchicalTrackSelectorWidget/components/util.js +11 -0
  19. package/dist/HierarchicalTrackSelectorWidget/components/util.js.map +1 -0
  20. package/dist/HierarchicalTrackSelectorWidget/configSchema.d.ts +2 -0
  21. package/dist/HierarchicalTrackSelectorWidget/configSchema.js +6 -0
  22. package/dist/HierarchicalTrackSelectorWidget/configSchema.js.map +1 -0
  23. package/dist/HierarchicalTrackSelectorWidget/index.d.ts +4 -2
  24. package/dist/HierarchicalTrackSelectorWidget/index.js +4 -4
  25. package/dist/HierarchicalTrackSelectorWidget/index.js.map +1 -1
  26. package/dist/HierarchicalTrackSelectorWidget/model.d.ts +10 -2
  27. package/dist/HierarchicalTrackSelectorWidget/model.js +35 -31
  28. package/dist/HierarchicalTrackSelectorWidget/model.js.map +1 -1
  29. package/dist/index.d.ts +4 -1
  30. package/dist/index.js +1 -1
  31. package/dist/index.js.map +1 -1
  32. package/esm/AddTrackWidget/components/AddTrackWidget.d.ts +2 -2
  33. package/esm/AddTrackWidget/components/AddTrackWidget.js +22 -135
  34. package/esm/AddTrackWidget/components/AddTrackWidget.js.map +1 -1
  35. package/esm/AddTrackWidget/components/ConfirmTrack.js +5 -6
  36. package/esm/AddTrackWidget/components/ConfirmTrack.js.map +1 -1
  37. package/esm/AddTrackWidget/components/DefaultAddTrackWorkflow.d.ts +7 -0
  38. package/esm/AddTrackWidget/components/DefaultAddTrackWorkflow.js +134 -0
  39. package/esm/AddTrackWidget/components/DefaultAddTrackWorkflow.js.map +1 -0
  40. package/esm/HierarchicalTrackSelectorWidget/components/Header.d.ts +10 -0
  41. package/esm/HierarchicalTrackSelectorWidget/components/Header.js +149 -0
  42. package/esm/HierarchicalTrackSelectorWidget/components/Header.js.map +1 -0
  43. package/esm/HierarchicalTrackSelectorWidget/components/HierarchicalTrackSelector.js +24 -223
  44. package/esm/HierarchicalTrackSelectorWidget/components/HierarchicalTrackSelector.js.map +1 -1
  45. package/esm/HierarchicalTrackSelectorWidget/components/Node.d.ts +29 -0
  46. package/esm/HierarchicalTrackSelectorWidget/components/Node.js +149 -0
  47. package/esm/HierarchicalTrackSelectorWidget/components/Node.js.map +1 -0
  48. package/esm/HierarchicalTrackSelectorWidget/components/util.d.ts +3 -0
  49. package/esm/HierarchicalTrackSelectorWidget/components/util.js +5 -0
  50. package/esm/HierarchicalTrackSelectorWidget/components/util.js.map +1 -0
  51. package/esm/HierarchicalTrackSelectorWidget/configSchema.d.ts +2 -0
  52. package/esm/HierarchicalTrackSelectorWidget/configSchema.js +4 -0
  53. package/esm/HierarchicalTrackSelectorWidget/configSchema.js.map +1 -0
  54. package/esm/HierarchicalTrackSelectorWidget/index.d.ts +4 -2
  55. package/esm/HierarchicalTrackSelectorWidget/index.js +3 -3
  56. package/esm/HierarchicalTrackSelectorWidget/index.js.map +1 -1
  57. package/esm/HierarchicalTrackSelectorWidget/model.d.ts +10 -2
  58. package/esm/HierarchicalTrackSelectorWidget/model.js +36 -32
  59. package/esm/HierarchicalTrackSelectorWidget/model.js.map +1 -1
  60. package/esm/index.d.ts +4 -1
  61. package/esm/index.js +1 -1
  62. package/esm/index.js.map +1 -1
  63. package/package.json +2 -2
  64. package/src/AddTrackWidget/components/{AddTrackWidget.test.js → AddTrackWidget.test.tsx} +17 -32
  65. package/src/AddTrackWidget/components/AddTrackWidget.tsx +36 -200
  66. package/src/AddTrackWidget/components/ConfirmTrack.tsx +10 -10
  67. package/src/AddTrackWidget/components/DefaultAddTrackWorkflow.tsx +205 -0
  68. package/src/HierarchicalTrackSelectorWidget/components/Header.tsx +287 -0
  69. package/src/HierarchicalTrackSelectorWidget/components/HierarchicalTrackSelector.tsx +19 -438
  70. package/src/HierarchicalTrackSelectorWidget/components/Node.tsx +284 -0
  71. package/src/HierarchicalTrackSelectorWidget/components/util.ts +11 -0
  72. package/src/HierarchicalTrackSelectorWidget/configSchema.ts +3 -0
  73. package/src/HierarchicalTrackSelectorWidget/index.ts +4 -6
  74. package/src/HierarchicalTrackSelectorWidget/model.ts +45 -41
  75. package/src/index.ts +4 -1
  76. package/src/AddTrackWidget/components/__snapshots__/AddTrackWidget.test.js.snap +0 -331
@@ -1,245 +1,47 @@
1
- import React, {
2
- Suspense,
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
- // lazy components
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
- onMoreInfo: setMoreInfo,
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
- <HierarchicalTrackSelectorHeader
262
+ <Header
682
263
  model={model}
683
264
  setHeaderHeight={setHeaderHeight}
684
265
  setAssemblyIdx={setAssemblyIdx}