From 5f39cc5cb8494f0a793a0dc68dfeba1d7e090d52 Mon Sep 17 00:00:00 2001 From: Colin Date: Sat, 21 Aug 2021 00:45:06 -0400 Subject: [PATCH 1/4] Import bookmarks function --- .../components/GridBookmarkWidget.tsx | 2 + .../components/ImportBookmarks.tsx | 97 +++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 plugins/grid-bookmark/src/GridBookmarkWidget/components/ImportBookmarks.tsx diff --git a/plugins/grid-bookmark/src/GridBookmarkWidget/components/GridBookmarkWidget.tsx b/plugins/grid-bookmark/src/GridBookmarkWidget/components/GridBookmarkWidget.tsx index cf5e88ed68..5796ca57aa 100644 --- a/plugins/grid-bookmark/src/GridBookmarkWidget/components/GridBookmarkWidget.tsx +++ b/plugins/grid-bookmark/src/GridBookmarkWidget/components/GridBookmarkWidget.tsx @@ -14,6 +14,7 @@ import ViewCompactIcon from '@material-ui/icons/ViewCompact' import AssemblySelector from './AssemblySelector' import DeleteBookmarkDialog from './DeleteBookmark' import DownloadBookmarks from './DownloadBookmarks' +import ImportBookmarks from './ImportBookmarks' import ClearBookmarks from './ClearBookmarks' // creates a coarse measurement of column width, similar to code in BaseFeatureDetails @@ -130,6 +131,7 @@ function GridBookmarkWidget({ model }: { model: GridBookmarkModel }) { <> + + setDialogOpen(false)}> + + setDialogOpen(false)} + > + + + +
+ <> +
+ + +
+ +
+
+ + ) +} + +export default observer(ImportBookmarks) From 3d94626d7e86f28718ca585e9d34059611fb41f0 Mon Sep 17 00:00:00 2001 From: Colin Date: Sat, 21 Aug 2021 01:51:11 -0400 Subject: [PATCH 2/4] Add import bookmarks function --- .../components/AssemblySelector.tsx | 18 +-- .../components/ClearBookmarks.tsx | 7 +- .../components/DeleteBookmark.tsx | 19 ++- .../components/GridBookmarkWidget.test.js | 4 +- .../components/GridBookmarkWidget.tsx | 90 ++++++------ .../components/ImportBookmarks.tsx | 138 +++++++++++++----- .../src/GridBookmarkWidget/model.ts | 72 ++++----- .../src/GridBookmarkWidget/utils.ts | 2 +- 8 files changed, 208 insertions(+), 142 deletions(-) diff --git a/plugins/grid-bookmark/src/GridBookmarkWidget/components/AssemblySelector.tsx b/plugins/grid-bookmark/src/GridBookmarkWidget/components/AssemblySelector.tsx index 87ed451e1b..c7d8a28c35 100644 --- a/plugins/grid-bookmark/src/GridBookmarkWidget/components/AssemblySelector.tsx +++ b/plugins/grid-bookmark/src/GridBookmarkWidget/components/AssemblySelector.tsx @@ -31,10 +31,6 @@ function AssemblySelector({ model }: { model: GridBookmarkModel }) { const { assemblies, selectedAssembly, setSelectedAssembly } = model const noAssemblies = assemblies.length === 0 ? true : false - const handleChange = (event: React.ChangeEvent<{ value: unknown }>) => { - setSelectedAssembly(event.target.value as string) - } - const determineCurrentValue = (selectedAssembly: string) => { if (selectedAssembly === 'all') { return 'all' @@ -53,7 +49,7 @@ function AssemblySelector({ model }: { model: GridBookmarkModel }) { diff --git a/plugins/grid-bookmark/src/GridBookmarkWidget/components/ClearBookmarks.tsx b/plugins/grid-bookmark/src/GridBookmarkWidget/components/ClearBookmarks.tsx index f659cf9541..ee23a4c27b 100644 --- a/plugins/grid-bookmark/src/GridBookmarkWidget/components/ClearBookmarks.tsx +++ b/plugins/grid-bookmark/src/GridBookmarkWidget/components/ClearBookmarks.tsx @@ -38,7 +38,7 @@ function ClearBookmarks({ model }: { model: GridBookmarkModel }) { aria-label="clear bookmarks" onClick={() => setDialogOpen(true)} > - Clear bookmarks + Clear setDialogOpen(false)}> @@ -52,7 +52,10 @@ function ClearBookmarks({ model }: { model: GridBookmarkModel }) {
<> - Clear all bookmarks? + + Clear all bookmarks? Note this will clear bookmarks for all + assemblies +
diff --git a/plugins/grid-bookmark/src/GridBookmarkWidget/components/ImportBookmarks.tsx b/plugins/grid-bookmark/src/GridBookmarkWidget/components/ImportBookmarks.tsx index 58b01255f7..8dbf82e826 100644 --- a/plugins/grid-bookmark/src/GridBookmarkWidget/components/ImportBookmarks.tsx +++ b/plugins/grid-bookmark/src/GridBookmarkWidget/components/ImportBookmarks.tsx @@ -1,20 +1,26 @@ import React, { useState } from 'react' import { observer } from 'mobx-react' - +import { getSession } from '@jbrowse/core/util' +import AssemblySelector from '@jbrowse/core/ui/AssemblySelector' +import { FileLocation } from '@jbrowse/core/util/types' +import { FileSelector } from '@jbrowse/core/ui' +import { openLocation } from '@jbrowse/core/util/io' import { IconButton, Button, Dialog, DialogTitle, + DialogContent, + DialogActions, + Grid, Select, MenuItem, makeStyles, + Typography, } from '@material-ui/core' import CloseIcon from '@material-ui/icons/Close' import ImportIcon from '@material-ui/icons/Publish' - import { GridBookmarkModel } from '../model' -import { downloadBookmarkFile } from '../utils' const useStyles = makeStyles(() => ({ closeDialog: { @@ -28,30 +34,35 @@ const useStyles = makeStyles(() => ({ flexItem: { margin: 5, }, - flexContainer: { - display: 'flex', - justifyContent: 'space-evenly', - width: 200, - }, })) -function ImportBookmarks({ model }: { model: GridBookmarkModel }) { +function ImportBookmarks({ + model, + assemblyName, +}: { + model: GridBookmarkModel + assemblyName: string +}) { const classes = useStyles() const [dialogOpen, setDialogOpen] = useState(false) + const [location, setLocation] = useState() + const [error, setError] = useState() const [fileType, setFileType] = useState('BED') - - const handleChange = (event: React.ChangeEvent<{ value: unknown }>) => { - setFileType(event.target.value as string) - } - - const { bookmarkedRegions } = model + const session = getSession(model) + const [selectedAsm, setSelectedAsm] = useState( + assemblyName || session.assemblyNames[0], + ) return ( <> - setDialogOpen(false)}> + setDialogOpen(false)} + maxWidth="xl" + > -
- <> -
+ + + + + Currently, only simple BED file imports are supported + - -
- -
+ + + Select assembly that your data belongs to + setSelectedAsm(val)} + session={session} + selected={selectedAsm} + /> + + + + + + {error ? ( + {`${error}`} + ) : null} + + + +
) diff --git a/plugins/grid-bookmark/src/GridBookmarkWidget/model.ts b/plugins/grid-bookmark/src/GridBookmarkWidget/model.ts index c5c9cb5e14..380a2b6412 100644 --- a/plugins/grid-bookmark/src/GridBookmarkWidget/model.ts +++ b/plugins/grid-bookmark/src/GridBookmarkWidget/model.ts @@ -1,15 +1,18 @@ -import { types, Instance } from 'mobx-state-tree' - +import { types, cast, Instance } from 'mobx-state-tree' import PluginManager from '@jbrowse/core/PluginManager' - -import { assembleLocString } from '@jbrowse/core/util' import { Region } from '@jbrowse/core/util/types' import { Region as RegionModel, ElementId } from '@jbrowse/core/util/types/mst' -const LabeledRegionModel = types.compose( - RegionModel, - types.model('Label', { label: '' }), -) +const LabeledRegionModel = types + .compose( + RegionModel, + types.model('Label', { label: types.optional(types.string, '') }), + ) + .actions(self => ({ + setLabel(label: string) { + self.label = label + }, + })) export default function f(pluginManager: PluginManager) { return types @@ -20,52 +23,41 @@ export default function f(pluginManager: PluginManager) { pluginManager.pluggableMstType('view', 'stateModel'), ), bookmarkedRegions: types.array(LabeledRegionModel), - selectedAssembly: '', + modelSelectedAssembly: '', }) .actions(self => ({ + importBookmarks(regions: Region[]) { + self.bookmarkedRegions = cast(self.bookmarkedRegions.concat(regions)) + }, addBookmark(region: Region) { - const regionLocString = assembleLocString(region) - const index = self.bookmarkedRegions.findIndex(b => { - const bLocString = assembleLocString(b) - return bLocString === regionLocString - }) - if (index === -1) { - self.bookmarkedRegions.push(region) - this.setSelectedAssembly(region.assemblyName) - } + self.bookmarkedRegions.push(region) }, - removeBookmark(locString: string) { - const index = self.bookmarkedRegions.findIndex(b => { - const bLocString = assembleLocString(b) - return bLocString === locString - }) - if (index !== -1) { - self.bookmarkedRegions.splice(index, 1) - } + removeBookmark(index: number) { + self.bookmarkedRegions.splice(index, 1) }, clearAllBookmarks() { self.bookmarkedRegions.clear() }, - updateBookmarkLabel(locString: string, label: string) { - const index = self.bookmarkedRegions.findIndex(b => { - const bLocString = assembleLocString(b) - return bLocString === locString - }) - if (index !== -1) { - self.bookmarkedRegions[index].label = label - } + updateBookmarkLabel(index: number, label: string) { + self.bookmarkedRegions[index]?.setLabel(label) }, setSelectedAssembly(assembly: string) { - self.selectedAssembly = assembly + self.modelSelectedAssembly = assembly }, })) .views(self => ({ - get assemblies() { - const assemblies = self.bookmarkedRegions.map( - region => region.assemblyName, + get selectedAssembly() { + return ( + self.modelSelectedAssembly || + (self.bookmarkedRegions.length + ? self.bookmarkedRegions[0].assemblyName + : '') ) - const uniqueAssemblies = Array.from(new Set(assemblies)) - return uniqueAssemblies + }, + get assemblies() { + return [ + ...new Set(self.bookmarkedRegions.map(region => region.assemblyName)), + ] }, })) } diff --git a/plugins/grid-bookmark/src/GridBookmarkWidget/utils.ts b/plugins/grid-bookmark/src/GridBookmarkWidget/utils.ts index c39e6748a6..90b411686f 100644 --- a/plugins/grid-bookmark/src/GridBookmarkWidget/utils.ts +++ b/plugins/grid-bookmark/src/GridBookmarkWidget/utils.ts @@ -77,7 +77,7 @@ export function downloadBookmarkFile( const fileContents = bookmarkedRegions .map(b => { const { label } = b - const labelVal = label === '' ? 'NA' : label + const labelVal = label === '' ? '.' : label const locString = assembleLocString(b) if (fileFormat === 'BED') { From ccdf6d5eb6f0a79256f034de68485242a9b93be6 Mon Sep 17 00:00:00 2001 From: Colin Date: Tue, 24 Aug 2021 19:55:58 -0400 Subject: [PATCH 3/4] Small refactors --- .../components/ClearBookmarks.tsx | 51 ++++++++------- .../components/DeleteBookmark.tsx | 51 +++++++++------ .../components/ImportBookmarks.tsx | 63 ++++++++----------- 3 files changed, 89 insertions(+), 76 deletions(-) diff --git a/plugins/grid-bookmark/src/GridBookmarkWidget/components/ClearBookmarks.tsx b/plugins/grid-bookmark/src/GridBookmarkWidget/components/ClearBookmarks.tsx index ee23a4c27b..a739efee85 100644 --- a/plugins/grid-bookmark/src/GridBookmarkWidget/components/ClearBookmarks.tsx +++ b/plugins/grid-bookmark/src/GridBookmarkWidget/components/ClearBookmarks.tsx @@ -6,6 +6,8 @@ import { IconButton, Dialog, DialogTitle, + DialogContent, + DialogActions, Typography, makeStyles, } from '@material-ui/core' @@ -42,6 +44,7 @@ function ClearBookmarks({ model }: { model: GridBookmarkModel }) { setDialogOpen(false)}> + Clear bookmarks -
- <> - - Clear all bookmarks? Note this will clear bookmarks for all - assemblies - -
-
- -
- -
+ + + Clear all bookmarks? Note this will clear bookmarks for all + assemblies + + + + + +
) diff --git a/plugins/grid-bookmark/src/GridBookmarkWidget/components/DeleteBookmark.tsx b/plugins/grid-bookmark/src/GridBookmarkWidget/components/DeleteBookmark.tsx index 36060e87dc..8aa223f5e9 100644 --- a/plugins/grid-bookmark/src/GridBookmarkWidget/components/DeleteBookmark.tsx +++ b/plugins/grid-bookmark/src/GridBookmarkWidget/components/DeleteBookmark.tsx @@ -8,6 +8,8 @@ import { Button, Dialog, DialogTitle, + DialogContent, + DialogActions, Typography, makeStyles, } from '@material-ui/core' @@ -42,6 +44,7 @@ function DeleteBookmarkDialog({ return ( + Delete bookmark -
+ - Remove row number{' '} + Remove{' '} {rowNumber !== undefined ? assembleLocString(model.bookmarkedRegions[rowNumber]) : ''} - + {' '} + ? -
-
- -
-
+ + + + + +
) } diff --git a/plugins/grid-bookmark/src/GridBookmarkWidget/components/ImportBookmarks.tsx b/plugins/grid-bookmark/src/GridBookmarkWidget/components/ImportBookmarks.tsx index 8dbf82e826..0be40eaf5a 100644 --- a/plugins/grid-bookmark/src/GridBookmarkWidget/components/ImportBookmarks.tsx +++ b/plugins/grid-bookmark/src/GridBookmarkWidget/components/ImportBookmarks.tsx @@ -44,13 +44,13 @@ function ImportBookmarks({ assemblyName: string }) { const classes = useStyles() + const session = getSession(model) + const { assemblyNames } = session const [dialogOpen, setDialogOpen] = useState(false) const [location, setLocation] = useState() const [error, setError] = useState() - const [fileType, setFileType] = useState('BED') - const session = getSession(model) - const [selectedAsm, setSelectedAsm] = useState( - assemblyName || session.assemblyNames[0], + const [selectedAsm, setSelectedAsm] = useState( + assemblyName || assemblyNames[0], ) return ( @@ -64,6 +64,7 @@ function ImportBookmarks({ maxWidth="xl" > + Import bookmarks - - - - Currently, only simple BED file imports are supported - - - - - Select assembly that your data belongs to - setSelectedAsm(val)} - session={session} - selected={selectedAsm} - /> - - - - - + + Choose a BED format file to import. The first 4 columns will be used + + + + Select assembly that your data belongs to + setSelectedAsm(val)} + session={session} + selected={selectedAsm} + /> {error ? ( {`${error}`} ) : null} + -
- -
+ + Format to download + + + + + +
) diff --git a/plugins/grid-bookmark/src/GridBookmarkWidget/components/ImportBookmarks.tsx b/plugins/grid-bookmark/src/GridBookmarkWidget/components/ImportBookmarks.tsx index 0be40eaf5a..d045e8e9bf 100644 --- a/plugins/grid-bookmark/src/GridBookmarkWidget/components/ImportBookmarks.tsx +++ b/plugins/grid-bookmark/src/GridBookmarkWidget/components/ImportBookmarks.tsx @@ -12,9 +12,6 @@ import { DialogTitle, DialogContent, DialogActions, - Grid, - Select, - MenuItem, makeStyles, Typography, } from '@material-ui/core'