@jbrowse/plugin-data-management 2.5.0 → 2.6.1
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/AddConnectionWidget/components/AddConnectionWidget.d.ts +2 -1
- package/dist/AddConnectionWidget/components/ConfigureConnection.d.ts +2 -1
- package/dist/AddConnectionWidget/components/ConnectionTypeSelect.d.ts +2 -1
- package/dist/AddTrackWidget/components/AddTrackWidget.d.ts +2 -1
- package/dist/AddTrackWidget/components/ConfirmTrack.d.ts +2 -1
- package/dist/AddTrackWidget/components/DefaultAddTrackWorkflow.d.ts +2 -1
- package/dist/AddTrackWidget/components/DefaultAddTrackWorkflow.js +1 -1
- package/dist/AddTrackWidget/components/DefaultAddTrackWorkflow.js.map +1 -1
- package/dist/AddTrackWidget/components/PasteConfigWorkflow.d.ts +2 -1
- package/dist/AddTrackWidget/components/PasteConfigWorkflow.js +1 -0
- package/dist/AddTrackWidget/components/PasteConfigWorkflow.js.map +1 -1
- package/dist/AddTrackWidget/components/TextIndexingConfig.d.ts +2 -1
- package/dist/AddTrackWidget/components/TrackAdapterSelector.d.ts +2 -1
- package/dist/AddTrackWidget/components/TrackSourceSelect.d.ts +2 -1
- package/dist/AddTrackWidget/components/TrackTypeSelector.d.ts +2 -1
- package/dist/AssemblyManager/AssemblyAddForm.d.ts +2 -1
- package/dist/AssemblyManager/AssemblyEditor.d.ts +2 -1
- package/dist/AssemblyManager/AssemblyManager.d.ts +2 -1
- package/dist/AssemblyManager/AssemblyTable.d.ts +2 -1
- package/dist/HierarchicalTrackSelectorWidget/components/HierarchicalFab.d.ts +2 -1
- package/dist/HierarchicalTrackSelectorWidget/components/HierarchicalTrackSelector.d.ts +2 -1
- package/dist/HierarchicalTrackSelectorWidget/components/HierarchicalTrackSelector.js +4 -9
- package/dist/HierarchicalTrackSelectorWidget/components/HierarchicalTrackSelector.js.map +1 -1
- package/dist/HierarchicalTrackSelectorWidget/components/ShoppingCart.d.ts +2 -1
- package/dist/HierarchicalTrackSelectorWidget/components/dialogs/CloseConnectionDialog.d.ts +8 -8
- package/dist/HierarchicalTrackSelectorWidget/components/dialogs/CloseConnectionDialog.js +6 -10
- package/dist/HierarchicalTrackSelectorWidget/components/dialogs/CloseConnectionDialog.js.map +1 -1
- package/dist/HierarchicalTrackSelectorWidget/components/dialogs/DeleteConnectionDialog.d.ts +2 -1
- package/dist/HierarchicalTrackSelectorWidget/components/dialogs/ManageConnectionsDialog.d.ts +2 -1
- package/dist/HierarchicalTrackSelectorWidget/components/dialogs/ToggleConnectionsDialog.d.ts +3 -3
- package/dist/HierarchicalTrackSelectorWidget/components/dialogs/ToggleConnectionsDialog.js +27 -22
- package/dist/HierarchicalTrackSelectorWidget/components/dialogs/ToggleConnectionsDialog.js.map +1 -1
- package/dist/HierarchicalTrackSelectorWidget/components/faceted/FacetFilters.d.ts +2 -1
- package/dist/HierarchicalTrackSelectorWidget/components/faceted/FacetedDialog.d.ts +2 -1
- package/dist/HierarchicalTrackSelectorWidget/components/faceted/FacetedHeader.d.ts +2 -1
- package/dist/HierarchicalTrackSelectorWidget/components/faceted/FacetedSelector.d.ts +2 -1
- package/dist/HierarchicalTrackSelectorWidget/components/faceted/FacetedSelector.js +32 -31
- package/dist/HierarchicalTrackSelectorWidget/components/faceted/FacetedSelector.js.map +1 -1
- package/dist/HierarchicalTrackSelectorWidget/components/tree/HamburgerMenu.d.ts +3 -3
- package/dist/HierarchicalTrackSelectorWidget/components/tree/HamburgerMenu.js +36 -41
- package/dist/HierarchicalTrackSelectorWidget/components/tree/HamburgerMenu.js.map +1 -1
- package/dist/HierarchicalTrackSelectorWidget/components/tree/HierarchicalHeader.d.ts +3 -3
- package/dist/HierarchicalTrackSelectorWidget/components/tree/HierarchicalHeader.js +2 -2
- package/dist/HierarchicalTrackSelectorWidget/components/tree/HierarchicalHeader.js.map +1 -1
- package/dist/HierarchicalTrackSelectorWidget/components/tree/HierarchicalTree.d.ts +2 -1
- package/dist/HierarchicalTrackSelectorWidget/components/tree/TrackCategory.d.ts +2 -1
- package/dist/HierarchicalTrackSelectorWidget/components/tree/TrackLabel.d.ts +2 -1
- package/dist/HierarchicalTrackSelectorWidget/components/tree/TrackListNode.d.ts +2 -1
- package/dist/HierarchicalTrackSelectorWidget/model.d.ts +69 -5
- package/dist/HierarchicalTrackSelectorWidget/model.js +100 -53
- package/dist/HierarchicalTrackSelectorWidget/model.js.map +1 -1
- package/dist/PluginStoreWidget/components/CustomPluginForm.d.ts +2 -1
- package/dist/PluginStoreWidget/components/InstalledPlugin.d.ts +2 -1
- package/dist/PluginStoreWidget/components/InstalledPluginsList.d.ts +2 -1
- package/dist/PluginStoreWidget/components/PluginCard.d.ts +2 -1
- package/dist/PluginStoreWidget/components/PluginStoreWidget.d.ts +2 -1
- package/dist/SetDefaultSession/SetDefaultSession.d.ts +2 -1
- package/dist/index.d.ts +4 -4
- package/dist/ucsc-trackhub/model.d.ts +12 -0
- package/dist/ucsc-trackhub/model.js +45 -12
- package/dist/ucsc-trackhub/model.js.map +1 -1
- package/esm/AddConnectionWidget/components/AddConnectionWidget.d.ts +2 -1
- package/esm/AddConnectionWidget/components/ConfigureConnection.d.ts +2 -1
- package/esm/AddConnectionWidget/components/ConnectionTypeSelect.d.ts +2 -1
- package/esm/AddTrackWidget/components/AddTrackWidget.d.ts +2 -1
- package/esm/AddTrackWidget/components/ConfirmTrack.d.ts +2 -1
- package/esm/AddTrackWidget/components/DefaultAddTrackWorkflow.d.ts +2 -1
- package/esm/AddTrackWidget/components/DefaultAddTrackWorkflow.js +1 -1
- package/esm/AddTrackWidget/components/DefaultAddTrackWorkflow.js.map +1 -1
- package/esm/AddTrackWidget/components/PasteConfigWorkflow.d.ts +2 -1
- package/esm/AddTrackWidget/components/PasteConfigWorkflow.js +1 -0
- package/esm/AddTrackWidget/components/PasteConfigWorkflow.js.map +1 -1
- package/esm/AddTrackWidget/components/TextIndexingConfig.d.ts +2 -1
- package/esm/AddTrackWidget/components/TrackAdapterSelector.d.ts +2 -1
- package/esm/AddTrackWidget/components/TrackSourceSelect.d.ts +2 -1
- package/esm/AddTrackWidget/components/TrackTypeSelector.d.ts +2 -1
- package/esm/AssemblyManager/AssemblyAddForm.d.ts +2 -1
- package/esm/AssemblyManager/AssemblyEditor.d.ts +2 -1
- package/esm/AssemblyManager/AssemblyManager.d.ts +2 -1
- package/esm/AssemblyManager/AssemblyTable.d.ts +2 -1
- package/esm/HierarchicalTrackSelectorWidget/components/HierarchicalFab.d.ts +2 -1
- package/esm/HierarchicalTrackSelectorWidget/components/HierarchicalTrackSelector.d.ts +2 -1
- package/esm/HierarchicalTrackSelectorWidget/components/HierarchicalTrackSelector.js +4 -9
- package/esm/HierarchicalTrackSelectorWidget/components/HierarchicalTrackSelector.js.map +1 -1
- package/esm/HierarchicalTrackSelectorWidget/components/ShoppingCart.d.ts +2 -1
- package/esm/HierarchicalTrackSelectorWidget/components/dialogs/CloseConnectionDialog.d.ts +8 -8
- package/esm/HierarchicalTrackSelectorWidget/components/dialogs/CloseConnectionDialog.js +7 -11
- package/esm/HierarchicalTrackSelectorWidget/components/dialogs/CloseConnectionDialog.js.map +1 -1
- package/esm/HierarchicalTrackSelectorWidget/components/dialogs/DeleteConnectionDialog.d.ts +2 -1
- package/esm/HierarchicalTrackSelectorWidget/components/dialogs/ManageConnectionsDialog.d.ts +2 -1
- package/esm/HierarchicalTrackSelectorWidget/components/dialogs/ToggleConnectionsDialog.d.ts +3 -3
- package/esm/HierarchicalTrackSelectorWidget/components/dialogs/ToggleConnectionsDialog.js +27 -22
- package/esm/HierarchicalTrackSelectorWidget/components/dialogs/ToggleConnectionsDialog.js.map +1 -1
- package/esm/HierarchicalTrackSelectorWidget/components/faceted/FacetFilters.d.ts +2 -1
- package/esm/HierarchicalTrackSelectorWidget/components/faceted/FacetedDialog.d.ts +2 -1
- package/esm/HierarchicalTrackSelectorWidget/components/faceted/FacetedHeader.d.ts +2 -1
- package/esm/HierarchicalTrackSelectorWidget/components/faceted/FacetedSelector.d.ts +2 -1
- package/esm/HierarchicalTrackSelectorWidget/components/faceted/FacetedSelector.js +32 -31
- package/esm/HierarchicalTrackSelectorWidget/components/faceted/FacetedSelector.js.map +1 -1
- package/esm/HierarchicalTrackSelectorWidget/components/tree/HamburgerMenu.d.ts +3 -3
- package/esm/HierarchicalTrackSelectorWidget/components/tree/HamburgerMenu.js +37 -42
- package/esm/HierarchicalTrackSelectorWidget/components/tree/HamburgerMenu.js.map +1 -1
- package/esm/HierarchicalTrackSelectorWidget/components/tree/HierarchicalHeader.d.ts +3 -3
- package/esm/HierarchicalTrackSelectorWidget/components/tree/HierarchicalHeader.js +2 -2
- package/esm/HierarchicalTrackSelectorWidget/components/tree/HierarchicalHeader.js.map +1 -1
- package/esm/HierarchicalTrackSelectorWidget/components/tree/HierarchicalTree.d.ts +2 -1
- package/esm/HierarchicalTrackSelectorWidget/components/tree/TrackCategory.d.ts +2 -1
- package/esm/HierarchicalTrackSelectorWidget/components/tree/TrackLabel.d.ts +2 -1
- package/esm/HierarchicalTrackSelectorWidget/components/tree/TrackListNode.d.ts +2 -1
- package/esm/HierarchicalTrackSelectorWidget/model.d.ts +69 -5
- package/esm/HierarchicalTrackSelectorWidget/model.js +101 -54
- package/esm/HierarchicalTrackSelectorWidget/model.js.map +1 -1
- package/esm/PluginStoreWidget/components/CustomPluginForm.d.ts +2 -1
- package/esm/PluginStoreWidget/components/InstalledPlugin.d.ts +2 -1
- package/esm/PluginStoreWidget/components/InstalledPluginsList.d.ts +2 -1
- package/esm/PluginStoreWidget/components/PluginCard.d.ts +2 -1
- package/esm/PluginStoreWidget/components/PluginStoreWidget.d.ts +2 -1
- package/esm/SetDefaultSession/SetDefaultSession.d.ts +2 -1
- package/esm/index.d.ts +4 -4
- package/esm/ucsc-trackhub/model.d.ts +12 -0
- package/esm/ucsc-trackhub/model.js +20 -10
- package/esm/ucsc-trackhub/model.js.map +1 -1
- package/package.json +2 -2
- package/src/AddConnectionWidget/components/AddConnectionWidget.test.tsx +1 -1
- package/src/AddTrackWidget/components/DefaultAddTrackWorkflow.tsx +1 -1
- package/src/AddTrackWidget/components/PasteConfigWorkflow.tsx +1 -0
- package/src/HierarchicalTrackSelectorWidget/components/HierarchicalTrackSelector.tsx +11 -21
- package/src/HierarchicalTrackSelectorWidget/components/__snapshots__/HierarchicalTrackSelector.test.tsx.snap +89 -24
- package/src/HierarchicalTrackSelectorWidget/components/dialogs/CloseConnectionDialog.tsx +9 -13
- package/src/HierarchicalTrackSelectorWidget/components/dialogs/ToggleConnectionsDialog.tsx +69 -39
- package/src/HierarchicalTrackSelectorWidget/components/faceted/FacetedSelector.tsx +14 -18
- package/src/HierarchicalTrackSelectorWidget/components/tree/HamburgerMenu.tsx +46 -51
- package/src/HierarchicalTrackSelectorWidget/components/tree/HierarchicalHeader.tsx +1 -3
- package/src/HierarchicalTrackSelectorWidget/model.ts +120 -65
- package/src/PluginStoreWidget/model.test.tsx +1 -1
- package/src/ucsc-trackhub/model.ts +28 -24
|
@@ -46,7 +46,7 @@ export default observer(function FacetedSelector({
|
|
|
46
46
|
}: {
|
|
47
47
|
model: HierarchicalTrackSelectorModel
|
|
48
48
|
}) {
|
|
49
|
-
const {
|
|
49
|
+
const { view, selection } = model
|
|
50
50
|
const { pluginManager } = getEnv(model)
|
|
51
51
|
const { ref, scrollLeft } = useResizeBar()
|
|
52
52
|
|
|
@@ -56,10 +56,9 @@ export default observer(function FacetedSelector({
|
|
|
56
56
|
const [useShoppingCart, setUseShoppingCart] = useState(false)
|
|
57
57
|
const [hideSparse, setHideSparse] = useState(true)
|
|
58
58
|
const [panelWidth, setPanelWidth] = useState(400)
|
|
59
|
-
|
|
60
|
-
const assemblyName = assemblyNames[0]
|
|
61
59
|
const session = getSession(model)
|
|
62
60
|
const filterDebounced = useDebounce(filterText, 400)
|
|
61
|
+
const tracks = view.tracks as AnyConfigurationModel[]
|
|
63
62
|
const [filters, dispatch] = useReducer(
|
|
64
63
|
(
|
|
65
64
|
state: Record<string, string[]>,
|
|
@@ -73,8 +72,7 @@ export default observer(function FacetedSelector({
|
|
|
73
72
|
const rows = useMemo(() => {
|
|
74
73
|
// metadata is spread onto the object for easier access and sorting
|
|
75
74
|
// by the mui data grid (it's unable to sort by nested objects)
|
|
76
|
-
return model
|
|
77
|
-
.trackConfigurations(assemblyName)
|
|
75
|
+
return model.trackConfigurations
|
|
78
76
|
.filter(conf => matches(filterDebounced, conf, session))
|
|
79
77
|
.map(track => {
|
|
80
78
|
const metadata = readConfObject(track, 'metadata')
|
|
@@ -89,7 +87,7 @@ export default observer(function FacetedSelector({
|
|
|
89
87
|
...metadata,
|
|
90
88
|
}
|
|
91
89
|
})
|
|
92
|
-
}, [
|
|
90
|
+
}, [model, filterDebounced, session])
|
|
93
91
|
|
|
94
92
|
const filteredNonMetadataKeys = useMemo(
|
|
95
93
|
() =>
|
|
@@ -109,9 +107,10 @@ export default observer(function FacetedSelector({
|
|
|
109
107
|
[hideSparse, rows],
|
|
110
108
|
)
|
|
111
109
|
|
|
112
|
-
const fields = useMemo(
|
|
113
|
-
|
|
114
|
-
|
|
110
|
+
const fields = useMemo(
|
|
111
|
+
() => ['name', ...filteredNonMetadataKeys, ...filteredMetadataKeys],
|
|
112
|
+
[filteredNonMetadataKeys, filteredMetadataKeys],
|
|
113
|
+
)
|
|
115
114
|
|
|
116
115
|
const [widths, setWidths] = useState({
|
|
117
116
|
name:
|
|
@@ -137,7 +136,7 @@ export default observer(function FacetedSelector({
|
|
|
137
136
|
),
|
|
138
137
|
]),
|
|
139
138
|
),
|
|
140
|
-
} as { [key: string]: number })
|
|
139
|
+
} as { [key: string]: number | undefined })
|
|
141
140
|
|
|
142
141
|
const [visible, setVisible] = useState(
|
|
143
142
|
Object.fromEntries(fields.map(c => [c, true])),
|
|
@@ -202,11 +201,11 @@ export default observer(function FacetedSelector({
|
|
|
202
201
|
</>
|
|
203
202
|
)
|
|
204
203
|
},
|
|
205
|
-
width: widthsDebounced.name
|
|
204
|
+
width: widthsDebounced.name ?? 100,
|
|
206
205
|
},
|
|
207
206
|
...filteredNonMetadataKeys.map(e => ({
|
|
208
207
|
field: e,
|
|
209
|
-
width: widthsDebounced[e]
|
|
208
|
+
width: widthsDebounced[e] ?? 100,
|
|
210
209
|
renderCell: (params: GridCellParams) => {
|
|
211
210
|
const { value } = params
|
|
212
211
|
return value ? <SanitizedHTML html={value as string} /> : ''
|
|
@@ -214,7 +213,7 @@ export default observer(function FacetedSelector({
|
|
|
214
213
|
})),
|
|
215
214
|
...filteredMetadataKeys.map(e => ({
|
|
216
215
|
field: e,
|
|
217
|
-
width: widthsDebounced[e]
|
|
216
|
+
width: widthsDebounced[e] ?? 100,
|
|
218
217
|
renderCell: (params: GridCellParams) => {
|
|
219
218
|
const { value } = params
|
|
220
219
|
return value ? <SanitizedHTML html={value as string} /> : ''
|
|
@@ -222,10 +221,7 @@ export default observer(function FacetedSelector({
|
|
|
222
221
|
})),
|
|
223
222
|
]
|
|
224
223
|
|
|
225
|
-
const shownTrackIds =
|
|
226
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
227
|
-
(t: any) => t.configuration.trackId,
|
|
228
|
-
) as string[]
|
|
224
|
+
const shownTrackIds = tracks.map(t => t.configuration.trackId as string)
|
|
229
225
|
|
|
230
226
|
const arrFilters = Object.entries(filters).filter(f => f[1].length > 0)
|
|
231
227
|
return (
|
|
@@ -271,7 +267,7 @@ export default observer(function FacetedSelector({
|
|
|
271
267
|
>
|
|
272
268
|
<ResizeBar
|
|
273
269
|
checkbox
|
|
274
|
-
widths={Object.values(widths)}
|
|
270
|
+
widths={Object.values(widths).map(f => f ?? 100)}
|
|
275
271
|
setWidths={newWidths =>
|
|
276
272
|
setWidths(
|
|
277
273
|
Object.fromEntries(
|
|
@@ -5,8 +5,10 @@ import { observer } from 'mobx-react'
|
|
|
5
5
|
import JBrowseMenu from '@jbrowse/core/ui/Menu'
|
|
6
6
|
import {
|
|
7
7
|
getSession,
|
|
8
|
-
|
|
8
|
+
isSessionModelWithConnectionEditing,
|
|
9
9
|
isSessionModelWithConnections,
|
|
10
|
+
isSessionModelWithWidgets,
|
|
11
|
+
isSessionWithAddTracks,
|
|
10
12
|
} from '@jbrowse/core/util'
|
|
11
13
|
import {
|
|
12
14
|
AnyConfigurationModel,
|
|
@@ -42,7 +44,7 @@ const useStyles = makeStyles()(theme => ({
|
|
|
42
44
|
|
|
43
45
|
interface ModalArgs {
|
|
44
46
|
connectionConf: AnyConfigurationModel
|
|
45
|
-
safelyBreakConnection:
|
|
47
|
+
safelyBreakConnection: () => void
|
|
46
48
|
dereferenceTypeCount: { [key: string]: number }
|
|
47
49
|
name: string
|
|
48
50
|
}
|
|
@@ -54,10 +56,8 @@ interface DialogDetails {
|
|
|
54
56
|
|
|
55
57
|
export default observer(function HamburgerMenu({
|
|
56
58
|
model,
|
|
57
|
-
setAssemblyIdx,
|
|
58
59
|
}: {
|
|
59
60
|
model: HierarchicalTrackSelectorModel
|
|
60
|
-
setAssemblyIdx: Function
|
|
61
61
|
}) {
|
|
62
62
|
const session = getSession(model)
|
|
63
63
|
const [menuEl, setMenuEl] = useState<HTMLButtonElement>()
|
|
@@ -66,7 +66,6 @@ export default observer(function HamburgerMenu({
|
|
|
66
66
|
const [connectionToggleOpen, setConnectionToggleOpen] = useState(false)
|
|
67
67
|
const [connectionManagerOpen, setConnectionManagerOpen] = useState(false)
|
|
68
68
|
const { classes } = useStyles()
|
|
69
|
-
const { assemblyNames } = model
|
|
70
69
|
|
|
71
70
|
function breakConnection(
|
|
72
71
|
connectionConf: AnyConfigurationModel,
|
|
@@ -92,30 +91,6 @@ export default observer(function HamburgerMenu({
|
|
|
92
91
|
}
|
|
93
92
|
}
|
|
94
93
|
|
|
95
|
-
const connectionMenuItems = [
|
|
96
|
-
{
|
|
97
|
-
label: 'Turn on/off connections...',
|
|
98
|
-
onClick: () => setConnectionToggleOpen(true),
|
|
99
|
-
},
|
|
100
|
-
]
|
|
101
|
-
|
|
102
|
-
if (isSessionModelWithConnections(session)) {
|
|
103
|
-
connectionMenuItems.unshift({
|
|
104
|
-
label: 'Add connection...',
|
|
105
|
-
onClick: () => {
|
|
106
|
-
if (isSessionModelWithWidgets(session)) {
|
|
107
|
-
session.showWidget(
|
|
108
|
-
session.addWidget('AddConnectionWidget', 'addConnectionWidget'),
|
|
109
|
-
)
|
|
110
|
-
}
|
|
111
|
-
},
|
|
112
|
-
})
|
|
113
|
-
|
|
114
|
-
connectionMenuItems.push({
|
|
115
|
-
label: 'Delete connections...',
|
|
116
|
-
onClick: () => setConnectionManagerOpen(true),
|
|
117
|
-
})
|
|
118
|
-
}
|
|
119
94
|
return (
|
|
120
95
|
<>
|
|
121
96
|
<IconButton
|
|
@@ -134,38 +109,58 @@ export default observer(function HamburgerMenu({
|
|
|
134
109
|
}}
|
|
135
110
|
onClose={() => setMenuEl(undefined)}
|
|
136
111
|
menuItems={[
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
112
|
+
...(isSessionWithAddTracks(session)
|
|
113
|
+
? [
|
|
114
|
+
{
|
|
115
|
+
label: 'Add track...',
|
|
116
|
+
onClick: () => {
|
|
117
|
+
if (isSessionModelWithWidgets(session)) {
|
|
118
|
+
session.showWidget(
|
|
119
|
+
session.addWidget('AddTrackWidget', 'addTrackWidget', {
|
|
120
|
+
view: model.view.id,
|
|
121
|
+
}),
|
|
122
|
+
)
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
]
|
|
127
|
+
: []),
|
|
128
|
+
...(isSessionModelWithConnections(session)
|
|
152
129
|
? [
|
|
153
130
|
{
|
|
154
|
-
label: '
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
131
|
+
label: 'Turn on/off connections...',
|
|
132
|
+
onClick: () => setConnectionToggleOpen(true),
|
|
133
|
+
},
|
|
134
|
+
]
|
|
135
|
+
: []),
|
|
136
|
+
...(isSessionModelWithConnectionEditing(session)
|
|
137
|
+
? [
|
|
138
|
+
{
|
|
139
|
+
label: 'Add connection...',
|
|
140
|
+
onClick: () => {
|
|
141
|
+
if (isSessionModelWithWidgets(session)) {
|
|
142
|
+
session.showWidget(
|
|
143
|
+
session.addWidget(
|
|
144
|
+
'AddConnectionWidget',
|
|
145
|
+
'addConnectionWidget',
|
|
146
|
+
),
|
|
147
|
+
)
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
label: 'Delete connections...',
|
|
153
|
+
onClick: () => setConnectionManagerOpen(true),
|
|
159
154
|
},
|
|
160
155
|
]
|
|
161
156
|
: []),
|
|
162
157
|
]}
|
|
163
158
|
/>
|
|
164
|
-
<Suspense fallback={<
|
|
159
|
+
<Suspense fallback={<React.Fragment />}>
|
|
165
160
|
{modalInfo ? (
|
|
166
161
|
<CloseConnectionDlg
|
|
167
162
|
modalInfo={modalInfo}
|
|
168
|
-
|
|
163
|
+
onClose={() => setModalInfo(undefined)}
|
|
169
164
|
/>
|
|
170
165
|
) : null}
|
|
171
166
|
{deleteDlgDetails ? (
|
|
@@ -27,11 +27,9 @@ const useStyles = makeStyles()(theme => ({
|
|
|
27
27
|
function HierarchicalTrackSelectorHeader({
|
|
28
28
|
model,
|
|
29
29
|
setHeaderHeight,
|
|
30
|
-
setAssemblyIdx,
|
|
31
30
|
}: {
|
|
32
31
|
model: HierarchicalTrackSelectorModel
|
|
33
32
|
setHeaderHeight: (n: number) => void
|
|
34
|
-
setAssemblyIdx: (n: number) => void
|
|
35
33
|
}) {
|
|
36
34
|
const { classes } = useStyles()
|
|
37
35
|
const [facetedOpen, setFacetedOpen] = useState(false)
|
|
@@ -43,7 +41,7 @@ function HierarchicalTrackSelectorHeader({
|
|
|
43
41
|
data-testid="hierarchical_track_selector"
|
|
44
42
|
>
|
|
45
43
|
<div style={{ display: 'flex' }}>
|
|
46
|
-
<HamburgerMenu model={model}
|
|
44
|
+
<HamburgerMenu model={model} />
|
|
47
45
|
<ShoppingCart model={model} />
|
|
48
46
|
|
|
49
47
|
<TextField
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
dedupe,
|
|
10
10
|
getSession,
|
|
11
11
|
getEnv,
|
|
12
|
+
notEmpty,
|
|
12
13
|
} from '@jbrowse/core/util'
|
|
13
14
|
import { getTrackName } from '@jbrowse/core/util/tracks'
|
|
14
15
|
import { ElementId } from '@jbrowse/core/util/types/mst'
|
|
@@ -49,22 +50,34 @@ export type TreeNode = {
|
|
|
49
50
|
|
|
50
51
|
function filterTracks(
|
|
51
52
|
tracks: AnyConfigurationModel[],
|
|
52
|
-
self: {
|
|
53
|
-
|
|
53
|
+
self: {
|
|
54
|
+
view: { type: string; trackSelectorAnyOverlap?: boolean }
|
|
55
|
+
assemblyNames: string[]
|
|
56
|
+
},
|
|
54
57
|
) {
|
|
55
58
|
const { assemblyManager } = getSession(self)
|
|
56
59
|
const { pluginManager } = getEnv(self)
|
|
57
|
-
const
|
|
60
|
+
const { view } = self
|
|
61
|
+
const { trackSelectorAnyOverlap } = view
|
|
62
|
+
const trackListAssemblies = self.assemblyNames
|
|
63
|
+
.map(a => assemblyManager.get(a))
|
|
64
|
+
.filter(notEmpty)
|
|
58
65
|
|
|
59
|
-
if (!assembly) {
|
|
60
|
-
return []
|
|
61
|
-
}
|
|
62
|
-
const { allAliases } = assembly
|
|
63
66
|
return tracks
|
|
64
|
-
.filter(c => hasAnyOverlap(allAliases, readConfObject(c, 'assemblyNames')))
|
|
65
67
|
.filter(c => {
|
|
66
|
-
const
|
|
67
|
-
const
|
|
68
|
+
const trackAssemblyNames = readConfObject(c, 'assemblyNames') as string[]
|
|
69
|
+
const trackAssemblies = new Set(
|
|
70
|
+
trackAssemblyNames
|
|
71
|
+
?.map(name => assemblyManager.get(name))
|
|
72
|
+
.filter(notEmpty) || [],
|
|
73
|
+
)
|
|
74
|
+
return trackSelectorAnyOverlap
|
|
75
|
+
? trackListAssemblies.some(a => trackAssemblies.has(a))
|
|
76
|
+
: trackListAssemblies.every(a => trackAssemblies.has(a))
|
|
77
|
+
})
|
|
78
|
+
.filter(c => {
|
|
79
|
+
const { displayTypes } = pluginManager.getViewType(view.type)
|
|
80
|
+
const compatDisplays = displayTypes.map(d => d.name)
|
|
68
81
|
const trackDisplays = c.displays.map((d: { type: string }) => d.type)
|
|
69
82
|
return hasAnyOverlap(compatDisplays, trackDisplays)
|
|
70
83
|
})
|
|
@@ -132,12 +145,27 @@ export function generateHierarchy(
|
|
|
132
145
|
return hierarchy.children
|
|
133
146
|
}
|
|
134
147
|
|
|
148
|
+
/**
|
|
149
|
+
* #stateModel HierarchicalTrackSelectorWidget
|
|
150
|
+
*/
|
|
135
151
|
export default function stateTreeFactory(pluginManager: PluginManager) {
|
|
136
152
|
return types
|
|
137
153
|
.model('HierarchicalTrackSelectorWidget', {
|
|
154
|
+
/**
|
|
155
|
+
* #property
|
|
156
|
+
*/
|
|
138
157
|
id: ElementId,
|
|
158
|
+
/**
|
|
159
|
+
* #property
|
|
160
|
+
*/
|
|
139
161
|
type: types.literal('HierarchicalTrackSelectorWidget'),
|
|
162
|
+
/**
|
|
163
|
+
* #property
|
|
164
|
+
*/
|
|
140
165
|
collapsed: types.map(types.boolean),
|
|
166
|
+
/**
|
|
167
|
+
* #property
|
|
168
|
+
*/
|
|
141
169
|
view: types.safeReference(
|
|
142
170
|
pluginManager.pluggableMstType('view', 'stateModel'),
|
|
143
171
|
),
|
|
@@ -147,33 +175,62 @@ export default function stateTreeFactory(pluginManager: PluginManager) {
|
|
|
147
175
|
filterText: '',
|
|
148
176
|
}))
|
|
149
177
|
.actions(self => ({
|
|
178
|
+
/**
|
|
179
|
+
* #action
|
|
180
|
+
*/
|
|
150
181
|
setSelection(elt: AnyConfigurationModel[]) {
|
|
151
182
|
self.selection = elt
|
|
152
183
|
},
|
|
184
|
+
/**
|
|
185
|
+
* #action
|
|
186
|
+
*/
|
|
153
187
|
addToSelection(elt: AnyConfigurationModel[]) {
|
|
154
188
|
self.selection = dedupe([...self.selection, ...elt], e => e.trackId)
|
|
155
189
|
},
|
|
190
|
+
/**
|
|
191
|
+
* #action
|
|
192
|
+
*/
|
|
156
193
|
removeFromSelection(elt: AnyConfigurationModel[]) {
|
|
157
194
|
self.selection = self.selection.filter(f => !elt.includes(f))
|
|
158
195
|
},
|
|
196
|
+
/**
|
|
197
|
+
* #action
|
|
198
|
+
*/
|
|
159
199
|
clearSelection() {
|
|
160
200
|
self.selection = []
|
|
161
201
|
},
|
|
202
|
+
/**
|
|
203
|
+
* #action
|
|
204
|
+
*/
|
|
162
205
|
setView(view: unknown) {
|
|
163
206
|
self.view = view
|
|
164
207
|
},
|
|
208
|
+
/**
|
|
209
|
+
* #action
|
|
210
|
+
*/
|
|
165
211
|
toggleCategory(pathName: string) {
|
|
166
212
|
self.collapsed.set(pathName, !self.collapsed.get(pathName))
|
|
167
213
|
},
|
|
214
|
+
/**
|
|
215
|
+
* #action
|
|
216
|
+
*/
|
|
168
217
|
clearFilterText() {
|
|
169
218
|
self.filterText = ''
|
|
170
219
|
},
|
|
220
|
+
/**
|
|
221
|
+
* #action
|
|
222
|
+
*/
|
|
171
223
|
setFilterText(newText: string) {
|
|
172
224
|
self.filterText = newText
|
|
173
225
|
},
|
|
174
226
|
}))
|
|
175
227
|
.views(self => ({
|
|
176
|
-
|
|
228
|
+
/**
|
|
229
|
+
* #method
|
|
230
|
+
*/
|
|
231
|
+
getRefSeqTrackConf(
|
|
232
|
+
assemblyName: string,
|
|
233
|
+
): AnyConfigurationModel | undefined {
|
|
177
234
|
const { assemblyManager } = getSession(self)
|
|
178
235
|
const assembly = assemblyManager.get(assemblyName)
|
|
179
236
|
const trackConf = assembly?.configuration.sequence
|
|
@@ -186,71 +243,67 @@ export default function stateTreeFactory(pluginManager: PluginManager) {
|
|
|
186
243
|
return trackConf
|
|
187
244
|
}
|
|
188
245
|
}
|
|
246
|
+
return undefined
|
|
189
247
|
},
|
|
190
248
|
}))
|
|
191
249
|
.views(self => ({
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
}
|
|
196
|
-
const { tracks, assemblyManager } = getSession(self)
|
|
197
|
-
const assembly = assemblyManager.get(assemblyName)
|
|
198
|
-
if (!assembly) {
|
|
199
|
-
return []
|
|
200
|
-
}
|
|
201
|
-
const refseq = self.getRefSeqTrackConf(assemblyName)
|
|
202
|
-
// filter out tracks that don't match the current assembly (check all
|
|
203
|
-
// assembly aliases) and display types
|
|
204
|
-
return [
|
|
205
|
-
...(refseq ? [refseq] : []),
|
|
206
|
-
...filterTracks(tracks, self, assemblyName),
|
|
207
|
-
]
|
|
208
|
-
},
|
|
209
|
-
|
|
250
|
+
/**
|
|
251
|
+
* #getter
|
|
252
|
+
*/
|
|
210
253
|
get assemblyNames(): string[] {
|
|
211
254
|
return self.view?.assemblyNames || []
|
|
212
255
|
},
|
|
256
|
+
}))
|
|
257
|
+
.views(self => ({
|
|
258
|
+
/**
|
|
259
|
+
* #method
|
|
260
|
+
* filter out tracks that don't match the current display types
|
|
261
|
+
*/
|
|
262
|
+
connectionTrackConfigurations(connection: {
|
|
263
|
+
tracks: AnyConfigurationModel[]
|
|
264
|
+
}) {
|
|
265
|
+
return !self.view ? [] : filterTracks(connection.tracks, self)
|
|
266
|
+
},
|
|
213
267
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
268
|
+
/**
|
|
269
|
+
* #getter
|
|
270
|
+
* filter out tracks that don't match the current assembly/display types
|
|
271
|
+
*/
|
|
272
|
+
get trackConfigurations(): AnyConfigurationModel[] {
|
|
273
|
+
return !self.view
|
|
274
|
+
? ([] as AnyConfigurationModel[])
|
|
275
|
+
: [
|
|
276
|
+
...self.assemblyNames.map(a => self.getRefSeqTrackConf(a)),
|
|
277
|
+
...filterTracks(getSession(self).tracks, self),
|
|
278
|
+
].filter(notEmpty)
|
|
224
279
|
},
|
|
225
280
|
}))
|
|
226
281
|
.views(self => ({
|
|
227
|
-
|
|
282
|
+
/**
|
|
283
|
+
* #getter
|
|
284
|
+
*/
|
|
285
|
+
get hierarchy() {
|
|
228
286
|
const hier = generateHierarchy(
|
|
229
|
-
|
|
230
|
-
self
|
|
231
|
-
self.trackConfigurations(assemblyName),
|
|
287
|
+
self as HierarchicalTrackSelectorModel,
|
|
288
|
+
self.trackConfigurations,
|
|
232
289
|
self.collapsed,
|
|
233
290
|
)
|
|
234
291
|
|
|
235
292
|
const session = getSession(self)
|
|
236
293
|
const { connectionInstances } = session
|
|
237
294
|
|
|
238
|
-
const { assemblyManager } = getSession(self)
|
|
239
|
-
const assembly = assemblyManager.get(assemblyName)
|
|
240
295
|
const conns =
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
.filter(f => f.children.length)) ||
|
|
253
|
-
[]
|
|
296
|
+
connectionInstances
|
|
297
|
+
?.map(c => ({
|
|
298
|
+
// @ts-expect-error
|
|
299
|
+
id: getSnapshot(c).configuration,
|
|
300
|
+
name: getConf(c, 'name'),
|
|
301
|
+
children: this.connectionHierarchy(c),
|
|
302
|
+
state: {
|
|
303
|
+
expanded: true,
|
|
304
|
+
},
|
|
305
|
+
}))
|
|
306
|
+
.filter(f => f.children.length) || []
|
|
254
307
|
|
|
255
308
|
return {
|
|
256
309
|
name: 'Root',
|
|
@@ -262,14 +315,16 @@ export default function stateTreeFactory(pluginManager: PluginManager) {
|
|
|
262
315
|
}
|
|
263
316
|
},
|
|
264
317
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
318
|
+
/**
|
|
319
|
+
* #method
|
|
320
|
+
*/
|
|
321
|
+
connectionHierarchy(connection: {
|
|
322
|
+
name: string
|
|
323
|
+
tracks: AnyConfigurationModel[]
|
|
324
|
+
}) {
|
|
269
325
|
return generateHierarchy(
|
|
270
|
-
|
|
271
|
-
self
|
|
272
|
-
self.connectionTrackConfigurations(assemblyName, connection),
|
|
326
|
+
self as HierarchicalTrackSelectorModel,
|
|
327
|
+
self.connectionTrackConfigurations(connection),
|
|
273
328
|
self.collapsed,
|
|
274
329
|
connection.name,
|
|
275
330
|
)
|
|
@@ -10,12 +10,6 @@ import { types } from 'mobx-state-tree'
|
|
|
10
10
|
|
|
11
11
|
// locals
|
|
12
12
|
import configSchema from './configSchema'
|
|
13
|
-
import {
|
|
14
|
-
fetchGenomesFile,
|
|
15
|
-
fetchHubFile,
|
|
16
|
-
fetchTrackDbFile,
|
|
17
|
-
generateTracks,
|
|
18
|
-
} from './ucscTrackHub'
|
|
19
13
|
|
|
20
14
|
export default function UCSCTrackHubConnection(pluginManager: PluginManager) {
|
|
21
15
|
return types
|
|
@@ -30,9 +24,15 @@ export default function UCSCTrackHubConnection(pluginManager: PluginManager) {
|
|
|
30
24
|
.actions(self => ({
|
|
31
25
|
async connect() {
|
|
32
26
|
const session = getSession(self)
|
|
27
|
+
const notLoadedAssemblies = [] as string[]
|
|
33
28
|
try {
|
|
34
|
-
const connectionName = getConf(self, 'name') // NOTE: name comes from the base configuration
|
|
35
29
|
const hubFileLocation = getConf(self, 'hubTxtLocation')
|
|
30
|
+
const {
|
|
31
|
+
generateTracks,
|
|
32
|
+
fetchGenomesFile,
|
|
33
|
+
fetchTrackDbFile,
|
|
34
|
+
fetchHubFile,
|
|
35
|
+
} = await import('./ucscTrackHub')
|
|
36
36
|
const hubFile = await fetchHubFile(hubFileLocation)
|
|
37
37
|
const genomeFile = hubFile.get('genomesFile')
|
|
38
38
|
if (!genomeFile) {
|
|
@@ -50,7 +50,7 @@ export default function UCSCTrackHubConnection(pluginManager: PluginManager) {
|
|
|
50
50
|
locationType: 'LocalPathLocation' as const,
|
|
51
51
|
}
|
|
52
52
|
const genomesFile = await fetchGenomesFile(genomesFileLocation)
|
|
53
|
-
const
|
|
53
|
+
const map = {} as { [key: string]: number }
|
|
54
54
|
for (const [genomeName, genome] of genomesFile) {
|
|
55
55
|
const assemblyNames = getConf(self, 'assemblyNames')
|
|
56
56
|
if (
|
|
@@ -62,16 +62,15 @@ export default function UCSCTrackHubConnection(pluginManager: PluginManager) {
|
|
|
62
62
|
|
|
63
63
|
const conf = session.assemblyManager.get(genomeName)?.configuration
|
|
64
64
|
if (!conf) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
)
|
|
65
|
+
notLoadedAssemblies.push(genomeName)
|
|
66
|
+
continue
|
|
68
67
|
}
|
|
69
68
|
const db = genome.get('trackDb')
|
|
70
69
|
if (!db) {
|
|
71
70
|
throw new Error('genomesFile not found on hub')
|
|
72
71
|
}
|
|
73
72
|
const base = new URL(genomeFile, hubUri)
|
|
74
|
-
const
|
|
73
|
+
const loc = hubUri
|
|
75
74
|
? {
|
|
76
75
|
uri: new URL(db, base).href,
|
|
77
76
|
locationType: 'UriLocation' as const,
|
|
@@ -80,20 +79,25 @@ export default function UCSCTrackHubConnection(pluginManager: PluginManager) {
|
|
|
80
79
|
localPath: db,
|
|
81
80
|
locationType: 'LocalPathLocation' as const,
|
|
82
81
|
}
|
|
83
|
-
const trackDb = await fetchTrackDbFile(
|
|
84
|
-
trackDbData.push([trackDbLoc, trackDb, genomeName, conf] as const)
|
|
85
|
-
}
|
|
86
|
-
for (const [
|
|
87
|
-
trackDbLoc,
|
|
88
|
-
trackDbFile,
|
|
89
|
-
genomeName,
|
|
90
|
-
conf,
|
|
91
|
-
] of trackDbData) {
|
|
82
|
+
const trackDb = await fetchTrackDbFile(loc)
|
|
92
83
|
const seqAdapter = readConfObject(conf, ['sequence', 'adapter'])
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
84
|
+
const tracks = generateTracks(trackDb, loc, genomeName, seqAdapter)
|
|
85
|
+
self.addTrackConfs(tracks)
|
|
86
|
+
map[genomeName] = tracks.length
|
|
96
87
|
}
|
|
88
|
+
|
|
89
|
+
const loadedAssemblies = Object.entries(map)
|
|
90
|
+
const str1 = loadedAssemblies.length
|
|
91
|
+
? `Loaded data from these assemblies: ${loadedAssemblies
|
|
92
|
+
.map(([key, val]) => `${key} (${val} tracks)`)
|
|
93
|
+
.join(', ')}`
|
|
94
|
+
: ''
|
|
95
|
+
const str2 = notLoadedAssemblies.length
|
|
96
|
+
? `Skipped data from these assemblies: ${notLoadedAssemblies.join(
|
|
97
|
+
', ',
|
|
98
|
+
)}`
|
|
99
|
+
: ''
|
|
100
|
+
session.notify([str1, str2].filter(f => !!f).join('. '), 'success')
|
|
97
101
|
} catch (e) {
|
|
98
102
|
console.error(e)
|
|
99
103
|
session.notify(
|