Skip to content

Commit

Permalink
Modularize drawer header into new component
Browse files Browse the repository at this point in the history
  • Loading branch information
cmdcolin committed Jul 19, 2023
1 parent 1a2161d commit a8318c1
Show file tree
Hide file tree
Showing 2 changed files with 203 additions and 178 deletions.
201 changes: 201 additions & 0 deletions packages/app-core/src/ui/App/DrawerHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
import React, { useState } from 'react'
import {
AppBar,
FormControl,
IconButton,
Menu,
MenuItem,
Select,
Toolbar,
Tooltip,
Typography,
} from '@mui/material'
import { makeStyles } from 'tss-react/mui'
import { observer } from 'mobx-react'
import { getEnv } from '@jbrowse/core/util'
import { SessionWithDrawerWidgets } from '@jbrowse/core/util/types'

// icons
import DeleteIcon from '@mui/icons-material/Delete'
import CloseIcon from '@mui/icons-material/Close'
import MinimizeIcon from '@mui/icons-material/Minimize'
import MoreVertIcon from '@mui/icons-material/MoreVert'

const useStyles = makeStyles()(theme => ({
formControl: {
margin: 0,
},
spacer: {
flexGrow: 1,
},
drawerSelect: {
margin: 0,
color: theme.palette.secondary.contrastText,
},

dropDownIcon: {
color: theme.palette.secondary.contrastText,
},
header: {
background: theme.palette.secondary.main,
},
}))

export default observer(function ({
session,
setToolbarHeight,
}: {
session: SessionWithDrawerWidgets
setToolbarHeight: (arg: number) => void
}) {
const { classes } = useStyles()

return (
<AppBar
position="sticky"
className={classes.header}
ref={ref => setToolbarHeight(ref?.getBoundingClientRect().height || 0)}
>
<Toolbar disableGutters>
<DrawerWidgetSelector session={session} />
<div className={classes.spacer} />
<DrawerControls session={session} />
</Toolbar>
</AppBar>
)
})

const DrawerWidgetSelector = observer(function ({
session,
}: {
session: SessionWithDrawerWidgets
}) {
const { visibleWidget, activeWidgets } = session
const { classes } = useStyles()
const { pluginManager } = getEnv(session)
return (
<FormControl className={classes.formControl}>
<Select
value={visibleWidget?.id}
data-testid="widget-drawer-selects"
className={classes.drawerSelect}
classes={{ icon: classes.dropDownIcon }}
renderValue={widgetId => {
const widget = session.activeWidgets.get(widgetId)
if (!widget) {
return (
<Typography variant="h6" color="inherit">
Unknown widget
</Typography>
)
}
const widgetType = pluginManager.getWidgetType(widget.type)
const { HeadingComponent, heading } = widgetType
return HeadingComponent ? (
<HeadingComponent model={widget} />
) : (
<Typography variant="h6" color="inherit">
{heading}
</Typography>
)
}}
onChange={e => {
const w = session.activeWidgets.get(e.target.value)
if (w) {
session.showWidget(w)
} else {
session.notify(`Widget not found ${e.target.value}`, 'warning')
}
}}
>
{[...activeWidgets.values()].map(widget => {
const widgetType = pluginManager.getWidgetType(widget.type)
const { HeadingComponent, heading } = widgetType
return (
<MenuItem
data-testid={`widget-drawer-selects-item-${widget.type}`}
key={widget.id}
value={widget.id}
>
{HeadingComponent ? (
<HeadingComponent model={widget} />
) : (
<Typography variant="h6" color="inherit">
{heading}
</Typography>
)}
<IconButton
data-testid={`${widget.type}-drawer-delete`}
color="inherit"
aria-label="Delete"
onClick={() => session.hideWidget(widget)}
>
<DeleteIcon />
</IconButton>
</MenuItem>
)
})}
</Select>
</FormControl>
)
})

const DrawerControls = observer(function ({
session,
}: {
session: SessionWithDrawerWidgets
}) {
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null)
const { drawerPosition, visibleWidget } = session
return (
<>
<IconButton
color="inherit"
onClick={event => setAnchorEl(event.currentTarget)}
>
<MoreVertIcon />
</IconButton>
<Tooltip title="Minimize drawer">
<IconButton
data-testid="drawer-minimize"
color="inherit"
onClick={() => {
session.notify(
`Drawer minimized, click button on ${drawerPosition} side of screen to re-open`,
'info',
)
session.minimizeWidgetDrawer()
}}
>
<MinimizeIcon />
</IconButton>
</Tooltip>
<Tooltip title="Close drawer">
<IconButton
color="inherit"
onClick={() => session.hideWidget(visibleWidget)}
>
<CloseIcon />
</IconButton>
</Tooltip>
<Menu
anchorEl={anchorEl}
open={Boolean(anchorEl)}
onClose={() => setAnchorEl(null)}
>
{['left', 'right'].map(option => (
<MenuItem
key={option}
selected={drawerPosition === 'option'}
onClick={() => {
session.setDrawerPosition(option)
setAnchorEl(null)
}}
>
{option}
</MenuItem>
))}
</Menu>
</>
)
})
180 changes: 2 additions & 178 deletions packages/app-core/src/ui/App/DrawerWidget.tsx
Original file line number Diff line number Diff line change
@@ -1,191 +1,15 @@
import React, { Suspense, useState } from 'react'
import { ErrorBoundary } from 'react-error-boundary'
import {
AppBar,
FormControl,
IconButton,
Menu,
MenuItem,
Select,
Toolbar,
Tooltip,
Typography,
} from '@mui/material'
import { makeStyles } from 'tss-react/mui'

import { observer } from 'mobx-react'
import { getEnv } from '@jbrowse/core/util'
import LoadingEllipses from '@jbrowse/core/ui/LoadingEllipses'
import ErrorMessage from '@jbrowse/core/ui/ErrorMessage'
import { SessionWithDrawerWidgets } from '@jbrowse/core/util/types'

// icons
import DeleteIcon from '@mui/icons-material/Delete'
import CloseIcon from '@mui/icons-material/Close'
import MinimizeIcon from '@mui/icons-material/Minimize'
import MoreVertIcon from '@mui/icons-material/MoreVert'

// locals
import Drawer from './Drawer'

const useStyles = makeStyles()(theme => ({
formControl: {
margin: 0,
},
spacer: {
flexGrow: 1,
},
drawerSelect: {
margin: 0,
color: theme.palette.secondary.contrastText,
},

dropDownIcon: {
color: theme.palette.secondary.contrastText,
},
header: {
background: theme.palette.secondary.main,
},
}))

const DrawerHeader = observer(function ({
session,
setToolbarHeight,
}: {
session: SessionWithDrawerWidgets
setToolbarHeight: (arg: number) => void
}) {
const { pluginManager } = getEnv(session)
const { visibleWidget, activeWidgets, drawerPosition } = session
const { classes } = useStyles()

const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null)

return (
<AppBar
position="sticky"
className={classes.header}
ref={ref => setToolbarHeight(ref?.getBoundingClientRect().height || 0)}
>
<Toolbar disableGutters>
<FormControl className={classes.formControl}>
<Select
value={visibleWidget?.id}
data-testid="widget-drawer-selects"
className={classes.drawerSelect}
classes={{ icon: classes.dropDownIcon }}
renderValue={widgetId => {
const widget = session.activeWidgets.get(widgetId)
if (!widget) {
return (
<Typography variant="h6" color="inherit">
Unknown widget
</Typography>
)
}
const widgetType = pluginManager.getWidgetType(widget.type)
const { HeadingComponent, heading } = widgetType
return HeadingComponent ? (
<HeadingComponent model={widget} />
) : (
<Typography variant="h6" color="inherit">
{heading}
</Typography>
)
}}
onChange={e => {
const w = session.activeWidgets.get(e.target.value)
if (w) {
session.showWidget(w)
} else {
session.notify(`Widget not found ${e.target.value}`, 'warning')
}
}}
>
{[...activeWidgets.values()].map(widget => {
const widgetType = pluginManager.getWidgetType(widget.type)
const { HeadingComponent, heading } = widgetType
return (
<MenuItem
data-testid={`widget-drawer-selects-item-${widget.type}`}
key={widget.id}
value={widget.id}
>
{HeadingComponent ? (
<HeadingComponent model={widget} />
) : (
<Typography variant="h6" color="inherit">
{heading}
</Typography>
)}
<IconButton
data-testid={`${widget.type}-drawer-delete`}
color="inherit"
aria-label="Delete"
onClick={() => session.hideWidget(widget)}
>
<DeleteIcon />
</IconButton>
</MenuItem>
)
})}
</Select>
</FormControl>
<div className={classes.spacer} />
<div>
<IconButton
data-testid="drawer-close"
color="inherit"
onClick={event => setAnchorEl(event.currentTarget)}
>
<MoreVertIcon />
</IconButton>
<Tooltip title="Minimize drawer">
<IconButton
data-testid="drawer-minimize"
color="inherit"
onClick={() => {
session.notify(
`Drawer minimized, click button on ${drawerPosition} side of screen to re-open`,
'info',
)
session.minimizeWidgetDrawer()
}}
>
<MinimizeIcon />
</IconButton>
</Tooltip>
<Tooltip title="Close drawer">
<IconButton
data-testid="drawer-close"
color="inherit"
onClick={() => session.hideWidget(visibleWidget)}
>
<CloseIcon />
</IconButton>
</Tooltip>
</div>
</Toolbar>
<Menu
anchorEl={anchorEl}
open={Boolean(anchorEl)}
onClose={() => setAnchorEl(null)}
>
{['left', 'right'].map(option => (
<MenuItem
key={option}
selected={drawerPosition === 'option'}
onClick={() => {
session.setDrawerPosition(option)
setAnchorEl(null)
}}
>
{option}
</MenuItem>
))}
</Menu>
</AppBar>
)
})
import DrawerHeader from './DrawerHeader'

const DrawerWidget = observer(function ({
session,
Expand Down

0 comments on commit a8318c1

Please sign in to comment.