@jbrowse/app-core 3.7.0 → 4.0.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/esm/AppFocus/index.d.ts +3 -3
- package/esm/AppFocus/index.js +1 -1
- package/esm/Assemblies/SessionAssembliesMixin.d.ts +47 -22
- package/esm/Assemblies/SessionAssembliesMixin.js +11 -1
- package/esm/Assemblies/TemporaryAssembliesMixin.d.ts +5 -3
- package/esm/Assemblies/TemporaryAssembliesMixin.js +11 -1
- package/esm/Assemblies/index.d.ts +2 -2
- package/esm/Assemblies/index.js +2 -2
- package/esm/DockviewLayout/index.d.ts +26 -0
- package/esm/DockviewLayout/index.js +107 -0
- package/esm/HistoryManagement/index.d.ts +7 -7
- package/esm/HistoryManagement/index.js +5 -6
- package/esm/JBrowseConfig/RootConfiguration.d.ts +15 -15
- package/esm/JBrowseConfig/index.d.ts +35 -25
- package/esm/JBrowseConfig/index.js +3 -3
- package/esm/JBrowseModel/index.d.ts +52 -34
- package/esm/JBrowseModel/index.js +15 -6
- package/esm/RootMenu/index.d.ts +3 -3
- package/esm/RootMenu/index.js +1 -1
- package/esm/index.d.ts +9 -8
- package/esm/index.js +9 -8
- package/esm/ui/App/App.d.ts +1 -1
- package/esm/ui/App/App.js +8 -8
- package/esm/ui/App/AppFab.js +2 -2
- package/esm/ui/App/AppToolbar.d.ts +1 -1
- package/esm/ui/App/AppToolbar.js +17 -3
- package/esm/ui/App/ClassicViewsContainer.d.ts +12 -0
- package/esm/ui/App/ClassicViewsContainer.js +21 -0
- package/esm/ui/App/DialogQueue.d.ts +2 -2
- package/esm/ui/App/DialogQueue.js +1 -1
- package/esm/ui/App/DockviewContext.d.ts +15 -0
- package/esm/ui/App/DockviewContext.js +21 -0
- package/esm/ui/App/DockviewLeftHeaderActions.d.ts +2 -0
- package/esm/ui/App/DockviewLeftHeaderActions.js +58 -0
- package/esm/ui/App/DockviewRightHeaderActions.d.ts +2 -0
- package/esm/ui/App/DockviewRightHeaderActions.js +100 -0
- package/esm/ui/App/Drawer.js +4 -5
- package/esm/ui/App/DrawerControls.js +1 -1
- package/esm/ui/App/DrawerHeader.js +16 -8
- package/{dist/ui/App/Drawer.d.ts → esm/ui/App/DrawerHeaderHelpButton.d.ts} +3 -3
- package/esm/ui/App/DrawerHeaderHelpButton.js +18 -0
- package/esm/ui/App/DrawerHeaderHelpDialog.d.ts +4 -0
- package/esm/ui/App/DrawerHeaderHelpDialog.js +15 -0
- package/esm/ui/App/DrawerWidget.js +4 -4
- package/esm/ui/App/DrawerWidgetSelector.js +3 -3
- package/esm/ui/App/JBrowseTabMenu.d.ts +5 -0
- package/esm/ui/App/JBrowseTabMenu.js +39 -0
- package/esm/ui/App/JBrowseViewPanel.d.ts +8 -0
- package/esm/ui/App/JBrowseViewPanel.js +49 -0
- package/esm/ui/App/JBrowseViewTab.d.ts +8 -0
- package/esm/ui/App/JBrowseViewTab.js +106 -0
- package/esm/ui/App/ModalWidget.js +3 -3
- package/esm/ui/App/TiledViewsContainer.d.ts +7 -0
- package/esm/ui/App/TiledViewsContainer.js +251 -0
- package/{dist/ui/App/ViewHeader.d.ts → esm/ui/App/ViewButtons.d.ts} +2 -3
- package/esm/ui/App/ViewButtons.js +17 -0
- package/esm/ui/App/ViewContainer.js +7 -8
- package/esm/ui/App/ViewContainerTitle.js +3 -4
- package/esm/ui/App/ViewHeader.js +7 -16
- package/esm/ui/App/ViewLauncher.d.ts +1 -1
- package/esm/ui/App/ViewLauncher.js +3 -4
- package/esm/ui/App/ViewMenu.d.ts +1 -1
- package/esm/ui/App/ViewMenu.js +113 -54
- package/esm/ui/App/ViewWrapper.js +1 -1
- package/esm/ui/App/ViewsContainer.d.ts +2 -2
- package/esm/ui/App/ViewsContainer.js +8 -6
- package/esm/ui/App/copyView.d.ts +1 -0
- package/esm/ui/App/copyView.js +29 -0
- package/esm/ui/App/dockviewUtils.d.ts +44 -0
- package/esm/ui/App/dockviewUtils.js +45 -0
- package/esm/ui/App/index.d.ts +2 -1
- package/esm/ui/App/index.js +2 -1
- package/esm/ui/App/types.d.ts +7 -0
- package/esm/ui/App/types.js +1 -0
- package/esm/ui/index.d.ts +1 -1
- package/esm/ui/index.js +1 -1
- package/package.json +27 -32
- package/dist/AppFocus/index.d.ts +0 -5
- package/dist/AppFocus/index.js +0 -15
- package/dist/Assemblies/SessionAssembliesMixin.d.ts +0 -67
- package/dist/Assemblies/SessionAssembliesMixin.js +0 -46
- package/dist/Assemblies/TemporaryAssembliesMixin.d.ts +0 -8
- package/dist/Assemblies/TemporaryAssembliesMixin.js +0 -30
- package/dist/Assemblies/index.d.ts +0 -2
- package/dist/Assemblies/index.js +0 -18
- package/dist/HistoryManagement/index.d.ts +0 -23
- package/dist/HistoryManagement/index.js +0 -47
- package/dist/JBrowseConfig/RootConfiguration.d.ts +0 -102
- package/dist/JBrowseConfig/RootConfiguration.js +0 -46
- package/dist/JBrowseConfig/index.d.ts +0 -115
- package/dist/JBrowseConfig/index.js +0 -26
- package/dist/JBrowseModel/index.d.ts +0 -142
- package/dist/JBrowseModel/index.js +0 -101
- package/dist/RootMenu/index.d.ts +0 -13
- package/dist/RootMenu/index.js +0 -74
- package/dist/index.d.ts +0 -8
- package/dist/index.js +0 -24
- package/dist/menus.d.ts +0 -74
- package/dist/menus.js +0 -108
- package/dist/ui/App/App.d.ts +0 -18
- package/dist/ui/App/App.js +0 -82
- package/dist/ui/App/AppFab.d.ts +0 -5
- package/dist/ui/App/AppFab.js +0 -32
- package/dist/ui/App/AppToolbar.d.ts +0 -18
- package/dist/ui/App/AppToolbar.js +0 -44
- package/dist/ui/App/DialogQueue.d.ts +0 -5
- package/dist/ui/App/DialogQueue.js +0 -10
- package/dist/ui/App/Drawer.js +0 -51
- package/dist/ui/App/DrawerControls.d.ts +0 -5
- package/dist/ui/App/DrawerControls.js +0 -30
- package/dist/ui/App/DrawerHeader.d.ts +0 -7
- package/dist/ui/App/DrawerHeader.js +0 -37
- package/dist/ui/App/DrawerWidget.d.ts +0 -5
- package/dist/ui/App/DrawerWidget.js +0 -65
- package/dist/ui/App/DrawerWidgetSelector.d.ts +0 -5
- package/dist/ui/App/DrawerWidgetSelector.js +0 -52
- package/dist/ui/App/ModalWidget.d.ts +0 -6
- package/dist/ui/App/ModalWidget.js +0 -53
- package/dist/ui/App/ViewContainer.d.ts +0 -6
- package/dist/ui/App/ViewContainer.js +0 -55
- package/dist/ui/App/ViewContainerTitle.d.ts +0 -5
- package/dist/ui/App/ViewContainerTitle.js +0 -44
- package/dist/ui/App/ViewHeader.js +0 -60
- package/dist/ui/App/ViewLauncher.d.ts +0 -11
- package/dist/ui/App/ViewLauncher.js +0 -29
- package/dist/ui/App/ViewMenu.d.ts +0 -8
- package/dist/ui/App/ViewMenu.js +0 -74
- package/dist/ui/App/ViewWrapper.d.ts +0 -6
- package/dist/ui/App/ViewWrapper.js +0 -23
- package/dist/ui/App/ViewsContainer.d.ts +0 -12
- package/dist/ui/App/ViewsContainer.js +0 -57
- package/dist/ui/App/index.d.ts +0 -1
- package/dist/ui/App/index.js +0 -17
- package/dist/ui/index.d.ts +0 -1
- package/dist/ui/index.js +0 -17
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import CascadingMenuButton from '@jbrowse/core/ui/CascadingMenuButton';
|
|
3
|
+
import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
4
|
+
import CloseIcon from '@mui/icons-material/Close';
|
|
5
|
+
import DynamicFeedIcon from '@mui/icons-material/DynamicFeed';
|
|
6
|
+
import MoreHorizIcon from '@mui/icons-material/MoreHoriz';
|
|
7
|
+
import TableRowsIcon from '@mui/icons-material/TableRows';
|
|
8
|
+
import ViewColumnIcon from '@mui/icons-material/ViewColumn';
|
|
9
|
+
import ViewModuleIcon from '@mui/icons-material/ViewModule';
|
|
10
|
+
import { IconButton, Tooltip } from '@mui/material';
|
|
11
|
+
import { useDockview } from "./DockviewContext.js";
|
|
12
|
+
import { rearrangePanelsWithDirection } from "./dockviewUtils.js";
|
|
13
|
+
const useStyles = makeStyles()(theme => ({
|
|
14
|
+
headerActions: {
|
|
15
|
+
display: 'flex',
|
|
16
|
+
alignItems: 'center',
|
|
17
|
+
height: '100%',
|
|
18
|
+
},
|
|
19
|
+
headerButton: {
|
|
20
|
+
padding: 4,
|
|
21
|
+
color: theme.palette.primary.contrastText,
|
|
22
|
+
},
|
|
23
|
+
headerIcon: {
|
|
24
|
+
fontSize: 16,
|
|
25
|
+
},
|
|
26
|
+
}));
|
|
27
|
+
export default function DockviewRightHeaderActions({ containerApi, group, }) {
|
|
28
|
+
const { classes } = useStyles();
|
|
29
|
+
const { rearrangePanels } = useDockview();
|
|
30
|
+
const tileHorizontally = () => {
|
|
31
|
+
rearrangePanels(api => {
|
|
32
|
+
rearrangePanelsWithDirection(api, (idx, states) => idx === 0
|
|
33
|
+
? undefined
|
|
34
|
+
: { referencePanel: states[0].id, direction: 'right' });
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
const tileVertically = () => {
|
|
38
|
+
rearrangePanels(api => {
|
|
39
|
+
rearrangePanelsWithDirection(api, (idx, states) => idx === 0
|
|
40
|
+
? undefined
|
|
41
|
+
: { referencePanel: states[0].id, direction: 'below' });
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
const tileGrid = () => {
|
|
45
|
+
rearrangePanels(api => {
|
|
46
|
+
const panels = api.panels;
|
|
47
|
+
if (panels.length <= 1) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const cols = Math.ceil(Math.sqrt(panels.length));
|
|
51
|
+
rearrangePanelsWithDirection(api, (idx, states) => {
|
|
52
|
+
if (idx === 0) {
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
const col = idx % cols;
|
|
56
|
+
const row = Math.floor(idx / cols);
|
|
57
|
+
if (col === 0) {
|
|
58
|
+
const refIdx = (row - 1) * cols;
|
|
59
|
+
return { referencePanel: states[refIdx].id, direction: 'below' };
|
|
60
|
+
}
|
|
61
|
+
return { referencePanel: states[idx - 1].id, direction: 'right' };
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
const stackAll = () => {
|
|
66
|
+
rearrangePanels(api => {
|
|
67
|
+
rearrangePanelsWithDirection(api, (idx, states) => idx === 0
|
|
68
|
+
? undefined
|
|
69
|
+
: { referencePanel: states[0].id, direction: 'within' });
|
|
70
|
+
});
|
|
71
|
+
};
|
|
72
|
+
const showLayoutOptions = containerApi.panels.length > 1;
|
|
73
|
+
const showCloseGroup = containerApi.groups.length > 1;
|
|
74
|
+
return (_jsxs("div", { className: classes.headerActions, children: [showLayoutOptions && (_jsx(CascadingMenuButton, { menuItems: [
|
|
75
|
+
{
|
|
76
|
+
label: 'Global: change layout into set of tabs',
|
|
77
|
+
icon: DynamicFeedIcon,
|
|
78
|
+
onClick: stackAll,
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
label: 'Global: tile horizontally',
|
|
82
|
+
icon: ViewColumnIcon,
|
|
83
|
+
onClick: tileHorizontally,
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
label: 'Global: tile vertically',
|
|
87
|
+
icon: TableRowsIcon,
|
|
88
|
+
onClick: tileVertically,
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
label: 'Global: tile grid',
|
|
92
|
+
icon: ViewModuleIcon,
|
|
93
|
+
onClick: tileGrid,
|
|
94
|
+
},
|
|
95
|
+
], size: "small", className: classes.headerButton, children: _jsx(MoreHorizIcon, { className: classes.headerIcon }) })), showCloseGroup && (_jsx(Tooltip, { title: "Close group", children: _jsx(IconButton, { size: "small", onClick: () => {
|
|
96
|
+
for (const panel of group.panels) {
|
|
97
|
+
panel.api.close();
|
|
98
|
+
}
|
|
99
|
+
}, className: classes.headerButton, children: _jsx(CloseIcon, { className: classes.headerIcon }) }) }))] }));
|
|
100
|
+
}
|
package/esm/ui/App/Drawer.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useRef } from 'react';
|
|
3
3
|
import ResizeHandle from '@jbrowse/core/ui/ResizeHandle';
|
|
4
|
+
import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
4
5
|
import { Paper } from '@mui/material';
|
|
5
6
|
import { observer } from 'mobx-react';
|
|
6
|
-
import { makeStyles } from 'tss-react/mui';
|
|
7
7
|
const useStyles = makeStyles()(theme => ({
|
|
8
8
|
paper: {
|
|
9
9
|
overflowY: 'auto',
|
|
@@ -20,15 +20,14 @@ const useStyles = makeStyles()(theme => ({
|
|
|
20
20
|
zIndex: theme.zIndex.drawer + 1,
|
|
21
21
|
},
|
|
22
22
|
}));
|
|
23
|
-
const Drawer = observer(function ({ children, session, }) {
|
|
23
|
+
const Drawer = observer(function Drawer({ children, session, }) {
|
|
24
24
|
const { drawerPosition, drawerWidth } = session;
|
|
25
25
|
const { classes } = useStyles();
|
|
26
26
|
const ref = useRef(null);
|
|
27
27
|
useEffect(() => {
|
|
28
28
|
function handleSelectView(e) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const visibleWidgetId = (_c = (_b = session.visibleWidget) === null || _b === void 0 ? void 0 : _b.view) === null || _c === void 0 ? void 0 : _c.id;
|
|
29
|
+
if (e.target instanceof Element && ref.current?.contains(e.target)) {
|
|
30
|
+
const visibleWidgetId = session.visibleWidget?.view?.id;
|
|
32
31
|
if (visibleWidgetId) {
|
|
33
32
|
session.setFocusedViewId(visibleWidgetId);
|
|
34
33
|
}
|
|
@@ -5,7 +5,7 @@ import MinimizeIcon from '@mui/icons-material/Minimize';
|
|
|
5
5
|
import MoreVertIcon from '@mui/icons-material/MoreVert';
|
|
6
6
|
import { IconButton, Menu, MenuItem, Tooltip } from '@mui/material';
|
|
7
7
|
import { observer } from 'mobx-react';
|
|
8
|
-
const DrawerControls = observer(function ({ session, }) {
|
|
8
|
+
const DrawerControls = observer(function DrawerControls({ session, }) {
|
|
9
9
|
const [anchorEl, setAnchorEl] = useState(null);
|
|
10
10
|
const { drawerPosition, visibleWidget } = session;
|
|
11
11
|
return (_jsxs(_Fragment, { children: [_jsx(IconButton, { color: "inherit", onClick: event => {
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Suspense, lazy } from 'react';
|
|
3
|
+
import { getEnv } from '@jbrowse/core/util';
|
|
4
|
+
import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
2
5
|
import LaunchIcon from '@mui/icons-material/Launch';
|
|
3
6
|
import { AppBar, IconButton, Toolbar, Tooltip } from '@mui/material';
|
|
4
7
|
import { observer } from 'mobx-react';
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
|
|
8
|
+
import DrawerControls from "./DrawerControls.js";
|
|
9
|
+
import DrawerWidgetSelector from "./DrawerWidgetSelector.js";
|
|
10
|
+
const DrawerHeaderHelpButton = lazy(() => import("./DrawerHeaderHelpButton.js"));
|
|
8
11
|
const useStyles = makeStyles()(theme => ({
|
|
9
12
|
spacer: {
|
|
10
13
|
flexGrow: 1,
|
|
@@ -16,17 +19,22 @@ const useStyles = makeStyles()(theme => ({
|
|
|
16
19
|
background: theme.palette.secondary.dark,
|
|
17
20
|
},
|
|
18
21
|
}));
|
|
19
|
-
const DrawerHeader = observer(function ({ session, setToolbarHeight, onPopoutDrawer, }) {
|
|
20
|
-
var _a, _b;
|
|
22
|
+
const DrawerHeader = observer(function DrawerHeader({ session, setToolbarHeight, onPopoutDrawer, }) {
|
|
21
23
|
const { classes } = useStyles();
|
|
22
24
|
const focusedViewId = session.focusedViewId;
|
|
23
|
-
const
|
|
25
|
+
const { visibleWidget } = session;
|
|
26
|
+
const viewWidgetId = visibleWidget?.view?.id;
|
|
27
|
+
const { pluginManager } = getEnv(session);
|
|
28
|
+
const widgetType = visibleWidget
|
|
29
|
+
? pluginManager.getWidgetType(visibleWidget.type)
|
|
30
|
+
: undefined;
|
|
31
|
+
const { helpText } = widgetType || {};
|
|
24
32
|
return (_jsx(AppBar, { position: "sticky", className: focusedViewId === viewWidgetId
|
|
25
33
|
? classes.headerFocused
|
|
26
34
|
: classes.headerUnfocused, ref: ref => {
|
|
27
|
-
setToolbarHeight(
|
|
35
|
+
setToolbarHeight(ref?.getBoundingClientRect().height || 0);
|
|
28
36
|
}, children: _jsxs(Toolbar, { disableGutters: true, children: [_jsx(DrawerWidgetSelector, { session: session }), _jsx(Tooltip, { title: "Open drawer in dialog", children: _jsx(IconButton, { color: "inherit", onClick: () => {
|
|
29
37
|
onPopoutDrawer();
|
|
30
|
-
}, children: _jsx(LaunchIcon, {}) }) }), _jsx("div", { className: classes.spacer }), _jsx(DrawerControls, { session: session })] }) }));
|
|
38
|
+
}, children: _jsx(LaunchIcon, {}) }) }), helpText ? (_jsx(Suspense, { fallback: null, children: _jsx(DrawerHeaderHelpButton, { helpText: helpText, session: session }) })) : null, _jsx("div", { className: classes.spacer }), _jsx(DrawerControls, { session: session })] }) }));
|
|
31
39
|
});
|
|
32
40
|
export default DrawerHeader;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { SessionWithFocusedViewAndDrawerWidgets } from '@jbrowse/core/util/types';
|
|
2
|
-
declare const
|
|
3
|
-
children: React.ReactNode;
|
|
2
|
+
declare const DrawerHeaderHelpButton: ({ session, helpText, }: {
|
|
4
3
|
session: SessionWithFocusedViewAndDrawerWidgets;
|
|
4
|
+
helpText: React.ReactNode;
|
|
5
5
|
}) => import("react/jsx-runtime").JSX.Element;
|
|
6
|
-
export default
|
|
6
|
+
export default DrawerHeaderHelpButton;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { lazy } from 'react';
|
|
3
|
+
import HelpOutline from '@mui/icons-material/HelpOutline';
|
|
4
|
+
import { IconButton, Tooltip } from '@mui/material';
|
|
5
|
+
import { observer } from 'mobx-react';
|
|
6
|
+
const DrawerHeaderHelpDialog = lazy(() => import("./DrawerHeaderHelpDialog.js"));
|
|
7
|
+
const DrawerHeaderHelpButton = observer(function DrawerHeaderHelpButton({ session, helpText, }) {
|
|
8
|
+
return (_jsx(Tooltip, { title: "Help", children: _jsx(IconButton, { color: "inherit", onClick: () => {
|
|
9
|
+
session.queueDialog(handleClose => [
|
|
10
|
+
DrawerHeaderHelpDialog,
|
|
11
|
+
{
|
|
12
|
+
onClose: handleClose,
|
|
13
|
+
helpText,
|
|
14
|
+
},
|
|
15
|
+
]);
|
|
16
|
+
}, children: _jsx(HelpOutline, {}) }) }));
|
|
17
|
+
});
|
|
18
|
+
export default DrawerHeaderHelpButton;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import Dialog from '@jbrowse/core/ui/Dialog';
|
|
3
|
+
import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
4
|
+
import { DialogContent } from '@mui/material';
|
|
5
|
+
const useStyles = makeStyles()({
|
|
6
|
+
max: {
|
|
7
|
+
minWidth: '40em',
|
|
8
|
+
},
|
|
9
|
+
});
|
|
10
|
+
export default function DrawerHeaderHelpDialog({ onClose, helpText, }) {
|
|
11
|
+
const { classes } = useStyles();
|
|
12
|
+
return (_jsx(Dialog, { open: true, onClose: onClose, title: "Help", maxWidth: "xl", onClick: e => {
|
|
13
|
+
e.stopPropagation();
|
|
14
|
+
}, children: _jsx(DialogContent, { className: classes.max, children: helpText }) }));
|
|
15
|
+
}
|
|
@@ -4,10 +4,10 @@ import { ErrorMessage, LoadingEllipses } from '@jbrowse/core/ui';
|
|
|
4
4
|
import { ErrorBoundary } from '@jbrowse/core/ui/ErrorBoundary';
|
|
5
5
|
import { getEnv } from '@jbrowse/core/util';
|
|
6
6
|
import { observer } from 'mobx-react';
|
|
7
|
-
import Drawer from
|
|
8
|
-
import DrawerHeader from
|
|
9
|
-
const ModalWidget = lazy(() => import(
|
|
10
|
-
const DrawerWidget = observer(function ({ session, }) {
|
|
7
|
+
import Drawer from "./Drawer.js";
|
|
8
|
+
import DrawerHeader from "./DrawerHeader.js";
|
|
9
|
+
const ModalWidget = lazy(() => import("./ModalWidget.js"));
|
|
10
|
+
const DrawerWidget = observer(function DrawerWidget({ session, }) {
|
|
11
11
|
const { visibleWidget } = session;
|
|
12
12
|
const { pluginManager } = getEnv(session);
|
|
13
13
|
const DrawerComponent = visibleWidget
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { getEnv } from '@jbrowse/core/util';
|
|
3
|
+
import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
3
4
|
import DeleteIcon from '@mui/icons-material/Delete';
|
|
4
5
|
import { FormControl, IconButton, MenuItem, Select, Typography, } from '@mui/material';
|
|
5
6
|
import { observer } from 'mobx-react';
|
|
6
|
-
import { makeStyles } from 'tss-react/mui';
|
|
7
7
|
const useStyles = makeStyles()(theme => ({
|
|
8
8
|
formControl: {
|
|
9
9
|
margin: 0,
|
|
@@ -16,11 +16,11 @@ const useStyles = makeStyles()(theme => ({
|
|
|
16
16
|
color: theme.palette.secondary.contrastText,
|
|
17
17
|
},
|
|
18
18
|
}));
|
|
19
|
-
const DrawerWidgetSelector = observer(function ({ session, }) {
|
|
19
|
+
const DrawerWidgetSelector = observer(function DrawerWidgetSelector({ session, }) {
|
|
20
20
|
const { visibleWidget, activeWidgets } = session;
|
|
21
21
|
const { classes } = useStyles();
|
|
22
22
|
const { pluginManager } = getEnv(session);
|
|
23
|
-
return (_jsx(FormControl, { className: classes.formControl, children: _jsx(Select, { value: visibleWidget
|
|
23
|
+
return (_jsx(FormControl, { className: classes.formControl, children: _jsx(Select, { value: visibleWidget?.id, "data-testid": "widget-drawer-selects", className: classes.drawerSelect, classes: { icon: classes.dropDownIcon }, renderValue: widgetId => {
|
|
24
24
|
const widget = session.activeWidgets.get(widgetId);
|
|
25
25
|
if (!widget) {
|
|
26
26
|
return (_jsx(Typography, { variant: "h6", color: "inherit", children: "Unknown widget" }));
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import CascadingMenuButton from '@jbrowse/core/ui/CascadingMenuButton';
|
|
3
|
+
import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
4
|
+
import CloseIcon from '@mui/icons-material/Close';
|
|
5
|
+
import EditIcon from '@mui/icons-material/Edit';
|
|
6
|
+
import MoreVertIcon from '@mui/icons-material/MoreVert';
|
|
7
|
+
const useStyles = makeStyles()({
|
|
8
|
+
tabIcons: {
|
|
9
|
+
display: 'flex',
|
|
10
|
+
alignItems: 'center',
|
|
11
|
+
visibility: 'hidden',
|
|
12
|
+
},
|
|
13
|
+
tabIconsVisible: {
|
|
14
|
+
visibility: 'visible',
|
|
15
|
+
},
|
|
16
|
+
tabIcon: {
|
|
17
|
+
padding: 2,
|
|
18
|
+
marginLeft: 2,
|
|
19
|
+
color: 'inherit',
|
|
20
|
+
},
|
|
21
|
+
smallIcon: {
|
|
22
|
+
fontSize: 14,
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
export default function JBrowseTabMenu({ isHovered, onRename, onClose, }) {
|
|
26
|
+
const { classes } = useStyles();
|
|
27
|
+
return (_jsx("div", { className: `${classes.tabIcons} ${isHovered ? classes.tabIconsVisible : ''}`, children: _jsx(CascadingMenuButton, { menuItems: [
|
|
28
|
+
{
|
|
29
|
+
label: 'Rename tab',
|
|
30
|
+
icon: EditIcon,
|
|
31
|
+
onClick: onRename,
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
label: 'Close tab',
|
|
35
|
+
icon: CloseIcon,
|
|
36
|
+
onClick: onClose,
|
|
37
|
+
},
|
|
38
|
+
], size: "small", className: classes.tabIcon, stopPropagation: true, children: _jsx(MoreVertIcon, { className: classes.smallIcon }) }) }));
|
|
39
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { DockviewSessionType } from './types.ts';
|
|
2
|
+
import type { IDockviewPanelProps } from 'dockview-react';
|
|
3
|
+
export interface JBrowseViewPanelParams {
|
|
4
|
+
panelId: string;
|
|
5
|
+
session?: DockviewSessionType;
|
|
6
|
+
}
|
|
7
|
+
declare const JBrowseViewPanel: ({ params, }: IDockviewPanelProps<JBrowseViewPanelParams>) => import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export default JBrowseViewPanel;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Suspense, lazy } from 'react';
|
|
3
|
+
import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
4
|
+
import { observer } from 'mobx-react';
|
|
5
|
+
import ViewContainer from "./ViewContainer.js";
|
|
6
|
+
import { isSessionWithDockviewLayout } from "../../DockviewLayout/index.js";
|
|
7
|
+
const ViewLauncher = lazy(() => import("./ViewLauncher.js"));
|
|
8
|
+
const useStyles = makeStyles()(theme => ({
|
|
9
|
+
container: {
|
|
10
|
+
height: '100%',
|
|
11
|
+
overflowY: 'auto',
|
|
12
|
+
background: theme.palette.background.default,
|
|
13
|
+
},
|
|
14
|
+
viewStack: {
|
|
15
|
+
display: 'flex',
|
|
16
|
+
flexDirection: 'column',
|
|
17
|
+
},
|
|
18
|
+
spacer: {
|
|
19
|
+
height: 300,
|
|
20
|
+
},
|
|
21
|
+
emptyPanel: {
|
|
22
|
+
display: 'flex',
|
|
23
|
+
alignItems: 'center',
|
|
24
|
+
justifyContent: 'center',
|
|
25
|
+
height: '100%',
|
|
26
|
+
},
|
|
27
|
+
}));
|
|
28
|
+
function getViewsForPanel(panelId, session) {
|
|
29
|
+
if (!session || !isSessionWithDockviewLayout(session)) {
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
const viewIds = session.getViewIdsForPanel(panelId);
|
|
33
|
+
return [...viewIds]
|
|
34
|
+
.map(id => session.views.find(v => v.id === id))
|
|
35
|
+
.filter((v) => v !== undefined);
|
|
36
|
+
}
|
|
37
|
+
const JBrowseViewPanel = observer(function JBrowseViewPanel({ params, }) {
|
|
38
|
+
const { panelId, session } = params;
|
|
39
|
+
const { classes } = useStyles();
|
|
40
|
+
if (!session) {
|
|
41
|
+
return _jsx("div", { className: classes.container, children: "Loading..." });
|
|
42
|
+
}
|
|
43
|
+
const views = getViewsForPanel(panelId, session);
|
|
44
|
+
if (views.length === 0) {
|
|
45
|
+
return (_jsx("div", { className: classes.container, children: _jsx("div", { className: classes.emptyPanel, children: _jsx(Suspense, { fallback: null, children: _jsx(ViewLauncher, { session: session }) }) }) }));
|
|
46
|
+
}
|
|
47
|
+
return (_jsx("div", { className: classes.container, children: _jsxs("div", { className: classes.viewStack, children: [views.map(view => (_jsx(ViewContainer, { view: view, session: session }, view.id))), _jsx("div", { className: classes.spacer })] }) }));
|
|
48
|
+
});
|
|
49
|
+
export default JBrowseViewPanel;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { DockviewSessionType } from './types.ts';
|
|
2
|
+
import type { IDockviewPanelHeaderProps } from 'dockview-react';
|
|
3
|
+
export interface JBrowseViewPanelParams {
|
|
4
|
+
panelId: string;
|
|
5
|
+
session?: DockviewSessionType;
|
|
6
|
+
}
|
|
7
|
+
declare const JBrowseViewTab: ({ params, api, }: IDockviewPanelHeaderProps<JBrowseViewPanelParams>) => import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export default JBrowseViewTab;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
4
|
+
import { InputBase, Typography } from '@mui/material';
|
|
5
|
+
import { observer } from 'mobx-react';
|
|
6
|
+
import JBrowseTabMenu from "./JBrowseTabMenu.js";
|
|
7
|
+
import { isSessionWithDockviewLayout } from "../../DockviewLayout/index.js";
|
|
8
|
+
const useStyles = makeStyles()(theme => ({
|
|
9
|
+
tabContainer: {
|
|
10
|
+
display: 'flex',
|
|
11
|
+
alignItems: 'center',
|
|
12
|
+
height: '100%',
|
|
13
|
+
padding: '0 4px',
|
|
14
|
+
gap: 4,
|
|
15
|
+
},
|
|
16
|
+
tabTitle: {
|
|
17
|
+
display: 'flex',
|
|
18
|
+
alignItems: 'center',
|
|
19
|
+
flex: 1,
|
|
20
|
+
overflow: 'hidden',
|
|
21
|
+
minWidth: 0,
|
|
22
|
+
},
|
|
23
|
+
tabTitleText: {
|
|
24
|
+
overflow: 'hidden',
|
|
25
|
+
textOverflow: 'ellipsis',
|
|
26
|
+
whiteSpace: 'nowrap',
|
|
27
|
+
fontSize: '0.8rem',
|
|
28
|
+
},
|
|
29
|
+
editInput: {
|
|
30
|
+
fontSize: '0.8rem',
|
|
31
|
+
padding: '2px 4px',
|
|
32
|
+
color: 'inherit',
|
|
33
|
+
backgroundColor: theme.palette.action.selected,
|
|
34
|
+
borderRadius: theme.shape.borderRadius,
|
|
35
|
+
flex: 1,
|
|
36
|
+
},
|
|
37
|
+
}));
|
|
38
|
+
function stopEvent(e) {
|
|
39
|
+
e.stopPropagation();
|
|
40
|
+
e.preventDefault();
|
|
41
|
+
}
|
|
42
|
+
function getViewsForPanel(panelId, session) {
|
|
43
|
+
if (!session || !isSessionWithDockviewLayout(session)) {
|
|
44
|
+
return [];
|
|
45
|
+
}
|
|
46
|
+
const viewIds = session.getViewIdsForPanel(panelId);
|
|
47
|
+
return [...viewIds]
|
|
48
|
+
.map(id => session.views.find(v => v.id === id))
|
|
49
|
+
.filter((v) => v !== undefined);
|
|
50
|
+
}
|
|
51
|
+
function getTabDisplayName(views, session) {
|
|
52
|
+
if (views.length === 0) {
|
|
53
|
+
return 'Empty';
|
|
54
|
+
}
|
|
55
|
+
if (views.length === 1) {
|
|
56
|
+
const view = views[0];
|
|
57
|
+
return (view.displayName ||
|
|
58
|
+
view.assemblyNames
|
|
59
|
+
?.map(r => session.assemblyManager.get(r)?.displayName)
|
|
60
|
+
.join(',') ||
|
|
61
|
+
'View');
|
|
62
|
+
}
|
|
63
|
+
return `${views.length} views`;
|
|
64
|
+
}
|
|
65
|
+
const JBrowseViewTab = observer(function JBrowseViewTab({ params, api, }) {
|
|
66
|
+
const { panelId, session } = params;
|
|
67
|
+
const { classes } = useStyles();
|
|
68
|
+
const [isEditing, setIsEditing] = useState(false);
|
|
69
|
+
const [isHovered, setIsHovered] = useState(false);
|
|
70
|
+
const [editValue, setEditValue] = useState('');
|
|
71
|
+
if (!session) {
|
|
72
|
+
return (_jsx("div", { className: classes.tabContainer, children: _jsx("span", { className: classes.tabTitleText, children: "Loading..." }) }));
|
|
73
|
+
}
|
|
74
|
+
const views = getViewsForPanel(panelId, session);
|
|
75
|
+
const displayValue = getTabDisplayName(views, session);
|
|
76
|
+
const handleStartEdit = () => {
|
|
77
|
+
setEditValue(api.title || displayValue);
|
|
78
|
+
setIsEditing(true);
|
|
79
|
+
};
|
|
80
|
+
const handleSave = () => {
|
|
81
|
+
if (editValue.trim()) {
|
|
82
|
+
api.setTitle(editValue.trim());
|
|
83
|
+
}
|
|
84
|
+
setIsEditing(false);
|
|
85
|
+
};
|
|
86
|
+
const handleKeyDown = (e) => {
|
|
87
|
+
if (e.key === 'Enter') {
|
|
88
|
+
handleSave();
|
|
89
|
+
}
|
|
90
|
+
else if (e.key === 'Escape') {
|
|
91
|
+
setIsEditing(false);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
return (_jsx("div", { className: classes.tabContainer, onMouseEnter: () => {
|
|
95
|
+
setIsHovered(true);
|
|
96
|
+
}, onMouseLeave: () => {
|
|
97
|
+
setIsHovered(false);
|
|
98
|
+
}, children: _jsx("div", { className: classes.tabTitle, children: isEditing ? (_jsx(InputBase, { autoFocus: true, className: classes.editInput, value: editValue, onChange: e => {
|
|
99
|
+
setEditValue(e.target.value);
|
|
100
|
+
}, onFocus: e => {
|
|
101
|
+
e.target.select();
|
|
102
|
+
}, onBlur: handleSave, onKeyDown: handleKeyDown, onClick: stopEvent })) : (_jsxs(_Fragment, { children: [_jsx(Typography, { className: classes.tabTitleText, variant: "body2", onDoubleClick: handleStartEdit, children: api.title || displayValue }), _jsx(JBrowseTabMenu, { isHovered: isHovered, onRename: handleStartEdit, onClose: () => {
|
|
103
|
+
api.close();
|
|
104
|
+
} })] })) }) }));
|
|
105
|
+
});
|
|
106
|
+
export default JBrowseViewTab;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Suspense } from 'react';
|
|
3
3
|
import { Dialog } from '@jbrowse/core/ui';
|
|
4
|
+
import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
5
|
+
import { getEnv } from '@jbrowse/mobx-state-tree';
|
|
4
6
|
import CloseIcon from '@mui/icons-material/Close';
|
|
5
7
|
import { AppBar, IconButton, Paper, Toolbar, Typography } from '@mui/material';
|
|
6
8
|
import { observer } from 'mobx-react';
|
|
7
|
-
import { getEnv } from 'mobx-state-tree';
|
|
8
|
-
import { makeStyles } from 'tss-react/mui';
|
|
9
9
|
const useStyles = makeStyles()(theme => ({
|
|
10
10
|
paper: {
|
|
11
11
|
overflow: 'auto',
|
|
@@ -28,7 +28,7 @@ const DrawerAppBar = observer(function DrawerAppBar({ session, onClose, }) {
|
|
|
28
28
|
const { HeadingComponent, heading } = pluginManager.getWidgetType(visibleWidget.type);
|
|
29
29
|
return (_jsxs(AppBar, { position: "static", children: [_jsx(Toolbar, { children: HeadingComponent ? (_jsx(HeadingComponent, { model: visibleWidget })) : (_jsx(Typography, { variant: "h6", children: heading })) }), _jsx(IconButton, { className: classes.closeButton, onClick: onClose, children: _jsx(CloseIcon, {}) })] }));
|
|
30
30
|
});
|
|
31
|
-
const ModalWidget = observer(function ({ session, onClose, }) {
|
|
31
|
+
const ModalWidget = observer(function ModalWidget({ session, onClose, }) {
|
|
32
32
|
const { classes } = useStyles();
|
|
33
33
|
const { visibleWidget } = session;
|
|
34
34
|
const { pluginManager } = getEnv(session);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { DockviewSessionType } from './types.ts';
|
|
2
|
+
import 'dockview-react/dist/styles/dockview.css';
|
|
3
|
+
interface Props {
|
|
4
|
+
session: DockviewSessionType;
|
|
5
|
+
}
|
|
6
|
+
declare const TiledViewsContainer: ({ session, }: Props) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export default TiledViewsContainer;
|