@jbrowse/app-core 2.6.1 → 2.6.3

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 (36) hide show
  1. package/dist/HistoryManagement/index.js +5 -2
  2. package/dist/JBrowseConfig/index.d.ts +29 -18
  3. package/dist/JBrowseConfig/index.js +8 -47
  4. package/dist/JBrowseModel/index.d.ts +38 -9
  5. package/dist/ui/App/DrawerHeader.d.ts +7 -0
  6. package/dist/ui/App/DrawerHeader.js +114 -0
  7. package/dist/ui/App/DrawerWidget.js +2 -76
  8. package/esm/HistoryManagement/index.js +5 -2
  9. package/esm/JBrowseConfig/index.d.ts +29 -18
  10. package/esm/JBrowseConfig/index.js +8 -47
  11. package/esm/JBrowseModel/index.d.ts +38 -9
  12. package/esm/ui/App/DrawerHeader.d.ts +7 -0
  13. package/esm/ui/App/DrawerHeader.js +86 -0
  14. package/esm/ui/App/DrawerWidget.js +1 -75
  15. package/package.json +6 -7
  16. package/src/Assemblies/SessionAssembliesMixin.ts +0 -50
  17. package/src/Assemblies/TemporaryAssembliesMixin.ts +0 -51
  18. package/src/Assemblies/index.ts +0 -2
  19. package/src/HistoryManagement/index.ts +0 -56
  20. package/src/JBrowseConfig/index.ts +0 -173
  21. package/src/JBrowseModel/index.ts +0 -150
  22. package/src/RootMenu/index.ts +0 -157
  23. package/src/index.ts +0 -6
  24. package/src/ui/App/App.tsx +0 -117
  25. package/src/ui/App/AppFab.tsx +0 -45
  26. package/src/ui/App/AppToolbar.tsx +0 -89
  27. package/src/ui/App/DialogQueue.tsx +0 -22
  28. package/src/ui/App/Drawer.tsx +0 -56
  29. package/src/ui/App/DrawerWidget.tsx +0 -238
  30. package/src/ui/App/ViewContainer.tsx +0 -76
  31. package/src/ui/App/ViewContainerTitle.tsx +0 -55
  32. package/src/ui/App/ViewLauncher.tsx +0 -64
  33. package/src/ui/App/ViewMenu.tsx +0 -54
  34. package/src/ui/App/ViewPanel.tsx +0 -63
  35. package/src/ui/App/index.ts +0 -1
  36. package/src/ui/index.ts +0 -1
@@ -1,89 +0,0 @@
1
- import React from 'react'
2
- import { Toolbar, Tooltip } from '@mui/material'
3
- import { makeStyles } from 'tss-react/mui'
4
- import { observer } from 'mobx-react'
5
- import { SessionWithDrawerWidgets } from '@jbrowse/core/util'
6
- import DropDownMenu from '@jbrowse/core/ui/DropDownMenu'
7
- import EditableTypography from '@jbrowse/core/ui/EditableTypography'
8
- import AppLogo from '@jbrowse/core/ui/AppLogo'
9
- import { MenuItem as JBMenuItem } from '@jbrowse/core/ui/Menu'
10
- import { SnackbarMessage } from '@jbrowse/core/ui/SnackbarModel'
11
-
12
- const useStyles = makeStyles()(theme => ({
13
- grow: {
14
- flexGrow: 1,
15
- },
16
- inputBase: {
17
- color: theme.palette.primary.contrastText,
18
- },
19
- inputRoot: {
20
- '&:hover': {
21
- backgroundColor: theme.palette.primary.light,
22
- },
23
- },
24
- inputFocused: {
25
- borderColor: theme.palette.secondary.main,
26
- backgroundColor: theme.palette.primary.light,
27
- },
28
- }))
29
-
30
- type AppSession = SessionWithDrawerWidgets & {
31
- savedSessionNames: string[]
32
- menus: { label: string; menuItems: JBMenuItem[] }[]
33
- renameCurrentSession: (arg: string) => void
34
- snackbarMessages: SnackbarMessage[]
35
- popSnackbarMessage: () => unknown
36
- }
37
-
38
- const AppToolbar = observer(function ({
39
- session,
40
- HeaderButtons = <div />,
41
- }: {
42
- HeaderButtons?: React.ReactElement
43
- session: AppSession
44
- }) {
45
- const { classes } = useStyles()
46
- const { savedSessionNames, name, menus } = session
47
-
48
- return (
49
- <Toolbar>
50
- {menus.map(menu => (
51
- <DropDownMenu
52
- key={menu.label}
53
- menuTitle={menu.label}
54
- menuItems={menu.menuItems}
55
- session={session}
56
- />
57
- ))}
58
- <div className={classes.grow} />
59
- <Tooltip title="Rename Session" arrow>
60
- <EditableTypography
61
- value={name}
62
- setValue={newName => {
63
- if (savedSessionNames?.includes(newName)) {
64
- session.notify(
65
- `Cannot rename session to "${newName}", a saved session with that name already exists`,
66
- 'warning',
67
- )
68
- } else {
69
- session.renameCurrentSession(newName)
70
- }
71
- }}
72
- variant="body1"
73
- classes={{
74
- inputBase: classes.inputBase,
75
- inputRoot: classes.inputRoot,
76
- inputFocused: classes.inputFocused,
77
- }}
78
- />
79
- </Tooltip>
80
- {HeaderButtons}
81
- <div className={classes.grow} />
82
- <div style={{ width: 150, maxHeight: 48 }}>
83
- <AppLogo session={session} />
84
- </div>
85
- </Toolbar>
86
- )
87
- })
88
-
89
- export default AppToolbar
@@ -1,22 +0,0 @@
1
- import React, { Suspense } from 'react'
2
- import { observer } from 'mobx-react'
3
-
4
- // locals
5
- import { SessionWithDrawerWidgets } from '@jbrowse/core/util'
6
-
7
- export default observer(function ({
8
- session,
9
- }: {
10
- session: SessionWithDrawerWidgets
11
- }) {
12
- const { DialogComponent, DialogProps } = session
13
- return (
14
- <>
15
- {DialogComponent ? (
16
- <Suspense fallback={<React.Fragment />}>
17
- <DialogComponent {...DialogProps} />
18
- </Suspense>
19
- ) : null}
20
- </>
21
- )
22
- })
@@ -1,56 +0,0 @@
1
- import React from 'react'
2
- import { Paper } from '@mui/material'
3
- import { makeStyles } from 'tss-react/mui'
4
- import { observer } from 'mobx-react'
5
- import ResizeHandle from '@jbrowse/core/ui/ResizeHandle'
6
- import { SessionWithDrawerWidgets } from '@jbrowse/core/util/types'
7
-
8
- const useStyles = makeStyles()(theme => ({
9
- paper: {
10
- overflowY: 'auto',
11
- height: '100%',
12
- zIndex: theme.zIndex.drawer,
13
- outline: 'none',
14
- background: theme.palette.background.default,
15
- },
16
- resizeHandle: {
17
- width: 4,
18
- position: 'fixed',
19
- top: 0,
20
- zIndex: theme.zIndex.drawer + 1,
21
- },
22
- }))
23
-
24
- function Drawer({
25
- children,
26
- session,
27
- }: {
28
- children: React.ReactNode
29
- session: SessionWithDrawerWidgets
30
- }) {
31
- const { drawerPosition, drawerWidth } = session
32
- const { classes } = useStyles()
33
-
34
- return (
35
- <Paper className={classes.paper} elevation={16} square>
36
- {drawerPosition === 'right' ? (
37
- <ResizeHandle
38
- onDrag={session.resizeDrawer}
39
- className={classes.resizeHandle}
40
- vertical
41
- />
42
- ) : null}
43
- {children}
44
- {drawerPosition === 'left' ? (
45
- <ResizeHandle
46
- onDrag={session.resizeDrawer}
47
- className={classes.resizeHandle}
48
- style={{ left: drawerWidth }}
49
- vertical
50
- />
51
- ) : null}
52
- </Paper>
53
- )
54
- }
55
-
56
- export default observer(Drawer)
@@ -1,238 +0,0 @@
1
- import React, { Suspense, useState } from 'react'
2
- import { ErrorBoundary } from 'react-error-boundary'
3
- import {
4
- AppBar,
5
- FormControl,
6
- IconButton,
7
- Menu,
8
- MenuItem,
9
- Select,
10
- Toolbar,
11
- Tooltip,
12
- Typography,
13
- } from '@mui/material'
14
- import { makeStyles } from 'tss-react/mui'
15
- import { observer } from 'mobx-react'
16
- import { getEnv } from '@jbrowse/core/util'
17
- import LoadingEllipses from '@jbrowse/core/ui/LoadingEllipses'
18
- import ErrorMessage from '@jbrowse/core/ui/ErrorMessage'
19
- import { SessionWithDrawerWidgets } from '@jbrowse/core/util/types'
20
-
21
- // icons
22
- import DeleteIcon from '@mui/icons-material/Delete'
23
- import CloseIcon from '@mui/icons-material/Close'
24
- import MinimizeIcon from '@mui/icons-material/Minimize'
25
- import MoreVertIcon from '@mui/icons-material/MoreVert'
26
-
27
- // locals
28
- import Drawer from './Drawer'
29
-
30
- const useStyles = makeStyles()(theme => ({
31
- formControl: {
32
- margin: 0,
33
- },
34
- spacer: {
35
- flexGrow: 1,
36
- },
37
- drawerSelect: {
38
- margin: 0,
39
- color: theme.palette.secondary.contrastText,
40
- },
41
-
42
- dropDownIcon: {
43
- color: theme.palette.secondary.contrastText,
44
- },
45
- header: {
46
- background: theme.palette.secondary.main,
47
- },
48
- }))
49
-
50
- const DrawerHeader = observer(function ({
51
- session,
52
- setToolbarHeight,
53
- }: {
54
- session: SessionWithDrawerWidgets
55
- setToolbarHeight: (arg: number) => void
56
- }) {
57
- const { pluginManager } = getEnv(session)
58
- const { visibleWidget, activeWidgets, drawerPosition } = session
59
- const { classes } = useStyles()
60
-
61
- const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null)
62
-
63
- return (
64
- <AppBar
65
- position="sticky"
66
- className={classes.header}
67
- ref={ref => setToolbarHeight(ref?.getBoundingClientRect().height || 0)}
68
- >
69
- <Toolbar disableGutters>
70
- <FormControl className={classes.formControl}>
71
- <Select
72
- value={visibleWidget?.id}
73
- data-testid="widget-drawer-selects"
74
- className={classes.drawerSelect}
75
- classes={{ icon: classes.dropDownIcon }}
76
- renderValue={widgetId => {
77
- const widget = session.activeWidgets.get(widgetId)
78
- if (!widget) {
79
- return (
80
- <Typography variant="h6" color="inherit">
81
- Unknown widget
82
- </Typography>
83
- )
84
- }
85
- const widgetType = pluginManager.getWidgetType(widget.type)
86
- const { HeadingComponent, heading } = widgetType
87
- return HeadingComponent ? (
88
- <HeadingComponent model={widget} />
89
- ) : (
90
- <Typography variant="h6" color="inherit">
91
- {heading}
92
- </Typography>
93
- )
94
- }}
95
- onChange={e => {
96
- const w = session.activeWidgets.get(e.target.value)
97
- if (w) {
98
- session.showWidget(w)
99
- } else {
100
- session.notify(`Widget not found ${e.target.value}`, 'warning')
101
- }
102
- }}
103
- >
104
- {[...activeWidgets.values()].map(widget => {
105
- const widgetType = pluginManager.getWidgetType(widget.type)
106
- const { HeadingComponent, heading } = widgetType
107
- return (
108
- <MenuItem
109
- data-testid={`widget-drawer-selects-item-${widget.type}`}
110
- key={widget.id}
111
- value={widget.id}
112
- >
113
- {HeadingComponent ? (
114
- <HeadingComponent model={widget} />
115
- ) : (
116
- <Typography variant="h6" color="inherit">
117
- {heading}
118
- </Typography>
119
- )}
120
- <IconButton
121
- data-testid={`${widget.type}-drawer-delete`}
122
- color="inherit"
123
- aria-label="Delete"
124
- onClick={() => session.hideWidget(widget)}
125
- >
126
- <DeleteIcon />
127
- </IconButton>
128
- </MenuItem>
129
- )
130
- })}
131
- </Select>
132
- </FormControl>
133
- <div className={classes.spacer} />
134
- <div>
135
- <IconButton
136
- data-testid="drawer-close"
137
- color="inherit"
138
- onClick={event => setAnchorEl(event.currentTarget)}
139
- >
140
- <MoreVertIcon />
141
- </IconButton>
142
- <Tooltip title="Minimize drawer">
143
- <IconButton
144
- data-testid="drawer-minimize"
145
- color="inherit"
146
- onClick={() => {
147
- session.notify(
148
- `Drawer minimized, click button on ${drawerPosition} side of screen to re-open`,
149
- 'info',
150
- )
151
- session.minimizeWidgetDrawer()
152
- }}
153
- >
154
- <MinimizeIcon />
155
- </IconButton>
156
- </Tooltip>
157
- <Tooltip title="Close drawer">
158
- <IconButton
159
- data-testid="drawer-close"
160
- color="inherit"
161
- onClick={() => session.hideWidget(visibleWidget)}
162
- >
163
- <CloseIcon />
164
- </IconButton>
165
- </Tooltip>
166
- </div>
167
- </Toolbar>
168
- <Menu
169
- anchorEl={anchorEl}
170
- open={Boolean(anchorEl)}
171
- onClose={() => setAnchorEl(null)}
172
- >
173
- {['left', 'right'].map(option => (
174
- <MenuItem
175
- key={option}
176
- selected={drawerPosition === 'option'}
177
- onClick={() => {
178
- session.setDrawerPosition(option)
179
- setAnchorEl(null)
180
- }}
181
- >
182
- {option}
183
- </MenuItem>
184
- ))}
185
- </Menu>
186
- </AppBar>
187
- )
188
- })
189
-
190
- const DrawerWidget = observer(function ({
191
- session,
192
- }: {
193
- session: SessionWithDrawerWidgets
194
- }) {
195
- const { visibleWidget } = session
196
- const { pluginManager } = getEnv(session)
197
-
198
- const DrawerComponent = visibleWidget
199
- ? (pluginManager.evaluateExtensionPoint(
200
- 'Core-replaceWidget',
201
- pluginManager.getWidgetType(visibleWidget.type).ReactComponent,
202
- {
203
- session,
204
- model: visibleWidget,
205
- },
206
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
207
- ) as React.FC<any>)
208
- : null
209
-
210
- // we track the toolbar height because components that use virtualized
211
- // height want to be able to fill the contained, minus the toolbar height
212
- // (the position static/sticky is included in AutoSizer estimates)
213
- const [toolbarHeight, setToolbarHeight] = useState(0)
214
-
215
- return (
216
- <Drawer session={session}>
217
- <DrawerHeader session={session} setToolbarHeight={setToolbarHeight} />
218
- <Suspense fallback={<LoadingEllipses />}>
219
- <ErrorBoundary
220
- FallbackComponent={({ error }) => <ErrorMessage error={error} />}
221
- >
222
- {DrawerComponent ? (
223
- <>
224
- <DrawerComponent
225
- model={visibleWidget}
226
- session={session}
227
- toolbarHeight={toolbarHeight}
228
- />
229
- <div style={{ height: 300 }} />
230
- </>
231
- ) : null}
232
- </ErrorBoundary>
233
- </Suspense>
234
- </Drawer>
235
- )
236
- })
237
-
238
- export default DrawerWidget
@@ -1,76 +0,0 @@
1
- import React, { useEffect, useRef } from 'react'
2
- import { IconButton, Paper, useTheme } from '@mui/material'
3
- import { makeStyles } from 'tss-react/mui'
4
- import { observer } from 'mobx-react'
5
- import { useWidthSetter } from '@jbrowse/core/util'
6
- import { IBaseViewModel } from '@jbrowse/core/pluggableElementTypes/models'
7
-
8
- // icons
9
- import CloseIcon from '@mui/icons-material/Close'
10
- import MinimizeIcon from '@mui/icons-material/Minimize'
11
- import AddIcon from '@mui/icons-material/Add'
12
-
13
- // locals
14
- import ViewMenu from './ViewMenu'
15
- import ViewContainerTitle from './ViewContainerTitle'
16
-
17
- const useStyles = makeStyles()(theme => ({
18
- viewContainer: {
19
- overflow: 'hidden',
20
- background: theme.palette.secondary.main,
21
- margin: theme.spacing(0.5),
22
- padding: `0 ${theme.spacing(1)} ${theme.spacing(1)}`,
23
- },
24
- icon: {
25
- color: theme.palette.secondary.contrastText,
26
- },
27
- grow: {
28
- flexGrow: 1,
29
- },
30
- }))
31
-
32
- export default observer(function ({
33
- view,
34
- onClose,
35
- onMinimize,
36
- children,
37
- }: {
38
- view: IBaseViewModel
39
- onClose: () => void
40
- onMinimize: () => void
41
- children: React.ReactNode
42
- }) {
43
- const { classes } = useStyles()
44
- const theme = useTheme()
45
- const ref = useWidthSetter(view, theme.spacing(1))
46
- const scrollRef = useRef<HTMLDivElement>(null)
47
-
48
- // scroll the view into view when first mounted. note: this effect will run
49
- // only once, because of the empty array second param
50
- useEffect(() => {
51
- scrollRef.current?.scrollIntoView?.({ block: 'center' })
52
- }, [])
53
-
54
- return (
55
- <Paper ref={ref} elevation={12} className={classes.viewContainer}>
56
- <div ref={scrollRef} style={{ display: 'flex' }}>
57
- <ViewMenu model={view} IconProps={{ className: classes.icon }} />
58
- <div className={classes.grow} />
59
-
60
- <ViewContainerTitle view={view} />
61
- <div className={classes.grow} />
62
- <IconButton data-testid="minimize_view" onClick={onMinimize}>
63
- {view.minimized ? (
64
- <AddIcon className={classes.icon} fontSize="small" />
65
- ) : (
66
- <MinimizeIcon className={classes.icon} fontSize="small" />
67
- )}
68
- </IconButton>
69
- <IconButton data-testid="close_view" onClick={onClose}>
70
- <CloseIcon className={classes.icon} fontSize="small" />
71
- </IconButton>
72
- </div>
73
- <Paper>{children}</Paper>
74
- </Paper>
75
- )
76
- })
@@ -1,55 +0,0 @@
1
- import React from 'react'
2
- import { Tooltip } from '@mui/material'
3
- import { makeStyles } from 'tss-react/mui'
4
- import { observer } from 'mobx-react'
5
-
6
- // locals
7
- import EditableTypography from '@jbrowse/core/ui/EditableTypography'
8
- import { IBaseViewModel } from '@jbrowse/core/pluggableElementTypes'
9
-
10
- const useStyles = makeStyles()(theme => ({
11
- input: {
12
- paddingBottom: 0,
13
- paddingTop: 2,
14
- },
15
- inputBase: {
16
- color: theme.palette.secondary.contrastText,
17
- },
18
- inputRoot: {
19
- '&:hover': {
20
- backgroundColor: theme.palette.secondary.light,
21
- },
22
- },
23
- inputFocused: {
24
- borderColor: theme.palette.primary.main,
25
- backgroundColor: theme.palette.secondary.light,
26
- },
27
- }))
28
- export default observer(function ViewContainerTitle({
29
- view,
30
- }: {
31
- view: IBaseViewModel
32
- }) {
33
- const { classes } = useStyles()
34
- return (
35
- <Tooltip title="Rename view" arrow>
36
- <EditableTypography
37
- value={
38
- view.displayName ||
39
- // @ts-expect-error
40
- `${view.assemblyNames?.join(',') || 'Untitled view'}${
41
- view.minimized ? ' (minimized)' : ''
42
- }`
43
- }
44
- setValue={val => view.setDisplayName(val)}
45
- variant="body2"
46
- classes={{
47
- input: classes.input,
48
- inputBase: classes.inputBase,
49
- inputRoot: classes.inputRoot,
50
- inputFocused: classes.inputFocused,
51
- }}
52
- />
53
- </Tooltip>
54
- )
55
- })
@@ -1,64 +0,0 @@
1
- import React, { useState } from 'react'
2
- import {
3
- Button,
4
- FormControl,
5
- MenuItem,
6
- Paper,
7
- Select,
8
- Typography,
9
- } from '@mui/material'
10
- import { observer } from 'mobx-react'
11
- import { makeStyles } from 'tss-react/mui'
12
-
13
- // locals
14
- import { getEnv, SessionWithDrawerWidgets } from '@jbrowse/core/util'
15
-
16
- // ui elements
17
- import { MenuItem as JBMenuItem } from '@jbrowse/core/ui/Menu'
18
- import { SnackbarMessage } from '@jbrowse/core/ui/SnackbarModel'
19
-
20
- type AppSession = SessionWithDrawerWidgets & {
21
- savedSessionNames: string[]
22
- menus: { label: string; menuItems: JBMenuItem[] }[]
23
- renameCurrentSession: (arg: string) => void
24
- snackbarMessages: SnackbarMessage[]
25
- popSnackbarMessage: () => unknown
26
- }
27
-
28
- const useStyles = makeStyles()(theme => ({
29
- selectPaper: {
30
- padding: theme.spacing(4),
31
- },
32
- }))
33
-
34
- const ViewLauncher = observer(({ session }: { session: AppSession }) => {
35
- const { classes } = useStyles()
36
- const { pluginManager } = getEnv(session)
37
- const viewTypes = pluginManager.getElementTypeRecord('view').all()
38
- const [value, setValue] = useState(viewTypes[0]?.name)
39
- return (
40
- <Paper className={classes.selectPaper}>
41
- <Typography>Select a view to launch</Typography>
42
- <FormControl style={{ margin: 2 }}>
43
- <Select value={value} onChange={event => setValue(event.target.value)}>
44
- {viewTypes.map(({ displayName, name }) => (
45
- <MenuItem key={name} value={name}>
46
- {displayName}
47
- </MenuItem>
48
- ))}
49
- </Select>
50
- </FormControl>
51
- <FormControl style={{ margin: 2 }}>
52
- <Button
53
- onClick={() => session.addView(value, {})}
54
- variant="contained"
55
- color="primary"
56
- >
57
- Launch view
58
- </Button>
59
- </FormControl>
60
- </Paper>
61
- )
62
- })
63
-
64
- export default ViewLauncher
@@ -1,54 +0,0 @@
1
- import React from 'react'
2
- import {
3
- SvgIconProps,
4
- IconButtonProps as IconButtonPropsType,
5
- } from '@mui/material'
6
- import { observer } from 'mobx-react'
7
- import { getSession } from '@jbrowse/core/util'
8
- import CascadingMenuButton from '@jbrowse/core/ui/CascadingMenuButton'
9
- import { IBaseViewModel } from '@jbrowse/core/pluggableElementTypes/models'
10
-
11
- // icons
12
- import MenuIcon from '@mui/icons-material/Menu'
13
- import ArrowDownward from '@mui/icons-material/ArrowDownward'
14
- import ArrowUpward from '@mui/icons-material/ArrowUpward'
15
-
16
- const ViewMenu = observer(function ({
17
- model,
18
- IconButtonProps,
19
- IconProps,
20
- }: {
21
- model: IBaseViewModel
22
- IconButtonProps?: IconButtonPropsType
23
- IconProps: SvgIconProps
24
- }) {
25
- const { menuItems } = model
26
- const session = getSession(model)
27
-
28
- const items = [
29
- ...(session.views.length > 1
30
- ? [
31
- {
32
- label: 'Move view up',
33
- icon: ArrowUpward,
34
- onClick: () => session.moveViewUp(model.id),
35
- },
36
- {
37
- label: 'Move view down',
38
- icon: ArrowDownward,
39
- onClick: () => session.moveViewDown(model.id),
40
- },
41
- ]
42
- : []),
43
-
44
- // <=1.3.3 didn't use a function, so check as value also
45
- ...((typeof menuItems === 'function' ? menuItems() : menuItems) || []),
46
- ]
47
-
48
- return items.length ? (
49
- <CascadingMenuButton menuItems={items} data-testid="view_menu_icon">
50
- <MenuIcon {...IconProps} fontSize="small" />
51
- </CascadingMenuButton>
52
- ) : null
53
- })
54
- export default ViewMenu