@jbrowse/app-core 4.3.0 → 5.0.0-beta.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/AppSession/AppRootModel.d.ts +30 -0
- package/esm/AppSession/AppRootModel.js +1 -0
- package/esm/AppSession/AppSessionMixin.d.ts +1598 -0
- package/esm/AppSession/AppSessionMixin.js +62 -0
- package/esm/AppSession/index.d.ts +2 -0
- package/esm/AppSession/index.js +1 -0
- package/esm/Assemblies/AssembliesMixin.d.ts +225 -0
- package/esm/Assemblies/AssembliesMixin.js +149 -0
- package/esm/Assemblies/index.d.ts +1 -2
- package/esm/Assemblies/index.js +1 -2
- package/esm/HistoryManagement/index.d.ts +19 -0
- package/esm/HistoryManagement/index.js +42 -5
- package/esm/JBrowseConfig/RootConfiguration.d.ts +167 -78
- package/esm/JBrowseConfig/RootConfiguration.js +85 -7
- package/esm/JBrowseConfig/index.d.ts +169 -84
- package/esm/JBrowseConfig/index.js +62 -2
- package/esm/JBrowseModel/index.d.ts +176 -95
- package/esm/JBrowseModel/index.js +122 -21
- package/esm/RootMenu/index.d.ts +77 -2
- package/esm/RootMenu/index.js +107 -61
- package/esm/SessionSpec/index.d.ts +6 -0
- package/esm/SessionSpec/index.js +3 -0
- package/esm/SessionSpec/lgvUrlInit.d.ts +79 -0
- package/esm/SessionSpec/lgvUrlInit.js +158 -0
- package/esm/SessionSpec/loadSessionSpec.d.ts +21 -0
- package/esm/SessionSpec/loadSessionSpec.js +311 -0
- package/esm/SessionSpec/parseSessionSpecUrl.d.ts +13 -0
- package/esm/SessionSpec/parseSessionSpecUrl.js +196 -0
- package/esm/SessionSpec/types.d.ts +33 -0
- package/esm/SessionSpec/types.js +1 -0
- package/esm/WorkspaceLayout/LayoutRenderer.d.ts +24 -0
- package/esm/WorkspaceLayout/LayoutRenderer.js +185 -0
- package/esm/WorkspaceLayout/PanelView.d.ts +13 -0
- package/esm/WorkspaceLayout/PanelView.js +99 -0
- package/esm/WorkspaceLayout/TabStrip.d.ts +14 -0
- package/esm/WorkspaceLayout/TabStrip.js +226 -0
- package/esm/WorkspaceLayout/WorkspaceContainer.d.ts +16 -0
- package/esm/WorkspaceLayout/WorkspaceContainer.js +105 -0
- package/esm/WorkspaceLayout/WorkspacePanelActions.d.ts +24 -0
- package/esm/WorkspaceLayout/WorkspacePanelActions.js +120 -0
- package/esm/WorkspaceLayout/WorkspaceTab.d.ts +27 -0
- package/esm/WorkspaceLayout/WorkspaceTab.js +109 -0
- package/esm/WorkspaceLayout/dockviewTheme.d.ts +69 -0
- package/esm/WorkspaceLayout/dockviewTheme.js +82 -0
- package/esm/WorkspaceLayout/dropZone.d.ts +105 -0
- package/esm/WorkspaceLayout/dropZone.js +113 -0
- package/esm/WorkspaceLayout/index.d.ts +8 -0
- package/esm/WorkspaceLayout/index.js +4 -0
- package/esm/WorkspaceLayout/model.d.ts +240 -0
- package/esm/WorkspaceLayout/model.js +527 -0
- package/esm/WorkspaceLayout/panelChrome.d.ts +19 -0
- package/esm/WorkspaceLayout/panelChrome.js +4 -0
- package/esm/WorkspaceLayout/spec.d.ts +58 -0
- package/esm/WorkspaceLayout/spec.js +153 -0
- package/esm/WorkspaceLayout/splitter.d.ts +25 -0
- package/esm/WorkspaceLayout/splitter.js +37 -0
- package/esm/WorkspaceLayout/tree.d.ts +158 -0
- package/esm/WorkspaceLayout/tree.js +379 -0
- package/esm/WorkspaceLayout/useLayoutDrag.d.ts +34 -0
- package/esm/WorkspaceLayout/useLayoutDrag.js +232 -0
- package/esm/index.d.ts +16 -9
- package/esm/index.js +13 -9
- package/esm/menus.d.ts +63 -62
- package/esm/menus.js +131 -84
- package/esm/queryParams.d.ts +9 -0
- package/esm/queryParams.js +92 -0
- package/esm/sessionModelFactory.d.ts +18 -0
- package/esm/sessionModelFactory.js +1 -0
- package/esm/ui/App/App.d.ts +3 -14
- package/esm/ui/App/App.js +30 -17
- package/esm/ui/App/AppFab.d.ts +12 -3
- package/esm/ui/App/AppFab.js +15 -8
- package/esm/ui/App/AppReadyMarker.d.ts +34 -0
- package/esm/ui/App/AppReadyMarker.js +56 -0
- package/esm/ui/App/AppToolbar.d.ts +2 -14
- package/esm/ui/App/AppToolbar.js +23 -24
- package/esm/ui/App/ClassicViewsContainer.d.ts +3 -9
- package/esm/ui/App/ClassicViewsContainer.js +9 -8
- package/esm/ui/App/DialogQueue.d.ts +17 -1
- package/esm/ui/App/DialogQueue.js +30 -1
- package/esm/ui/App/Drawer.d.ts +1 -1
- package/esm/ui/App/Drawer.js +10 -39
- package/esm/ui/App/DrawerControls.d.ts +1 -5
- package/esm/ui/App/DrawerControls.js +1 -25
- package/esm/ui/App/DrawerHeader.d.ts +2 -3
- package/esm/ui/App/DrawerHeader.js +24 -10
- package/esm/ui/App/DrawerHeaderHelpButton.d.ts +1 -1
- package/esm/ui/App/DrawerHeaderHelpButton.js +3 -3
- package/esm/ui/App/DrawerHeaderHelpDialog.d.ts +2 -2
- package/esm/ui/App/DrawerHeaderHelpDialog.js +3 -4
- package/esm/ui/App/DrawerWidget.d.ts +1 -1
- package/esm/ui/App/DrawerWidget.js +9 -21
- package/esm/ui/App/JBrowseTabMenu.d.ts +2 -3
- package/esm/ui/App/JBrowseTabMenu.js +24 -5
- package/esm/ui/App/ViewButtons.d.ts +2 -4
- package/esm/ui/App/ViewButtons.js +15 -3
- package/esm/ui/App/ViewContainer.d.ts +3 -2
- package/esm/ui/App/ViewContainer.js +144 -24
- package/esm/ui/App/ViewContainerTitle.d.ts +1 -1
- package/esm/ui/App/ViewContainerTitle.js +9 -2
- package/esm/ui/App/ViewErrorFallback.d.ts +18 -0
- package/esm/ui/App/ViewErrorFallback.js +42 -0
- package/esm/ui/App/ViewHeader.d.ts +3 -4
- package/esm/ui/App/ViewHeader.js +28 -17
- package/esm/ui/App/ViewLauncher.d.ts +2 -8
- package/esm/ui/App/ViewLauncher.js +7 -5
- package/esm/ui/App/ViewMenu.d.ts +3 -5
- package/esm/ui/App/ViewMenu.js +87 -92
- package/esm/ui/App/ViewStack.d.ts +7 -0
- package/esm/ui/App/ViewStack.js +42 -0
- package/esm/ui/App/ViewWrapper.d.ts +15 -1
- package/esm/ui/App/ViewWrapper.js +26 -10
- package/esm/ui/App/ViewsContainer.d.ts +3 -8
- package/esm/ui/App/ViewsContainer.js +9 -6
- package/esm/ui/App/copyView.js +1 -1
- package/esm/ui/App/index.d.ts +2 -1
- package/esm/ui/App/index.js +3 -2
- package/esm/ui/App/lazyChunk.d.ts +13 -0
- package/esm/ui/App/lazyChunk.js +91 -0
- package/esm/ui/App/types.d.ts +12 -3
- package/esm/ui/App/types.js +1 -1
- package/esm/ui/App/useViewVisibility.d.ts +34 -0
- package/esm/ui/App/useViewVisibility.js +87 -0
- package/esm/ui/App/viewTitle.d.ts +5 -0
- package/esm/ui/App/viewTitle.js +9 -0
- package/esm/ui/index.d.ts +1 -1
- package/esm/ui/index.js +1 -1
- package/package.json +12 -17
- package/esm/AppFocus/index.d.ts +0 -5
- package/esm/AppFocus/index.js +0 -12
- package/esm/Assemblies/SessionAssembliesMixin.d.ts +0 -92
- package/esm/Assemblies/SessionAssembliesMixin.js +0 -53
- package/esm/Assemblies/TemporaryAssembliesMixin.d.ts +0 -10
- package/esm/Assemblies/TemporaryAssembliesMixin.js +0 -37
- package/esm/DockviewLayout/index.d.ts +0 -35
- package/esm/DockviewLayout/index.js +0 -111
- package/esm/ui/App/DockviewContext.d.ts +0 -22
- package/esm/ui/App/DockviewContext.js +0 -29
- package/esm/ui/App/DockviewLeftHeaderActions.d.ts +0 -2
- package/esm/ui/App/DockviewLeftHeaderActions.js +0 -58
- package/esm/ui/App/DockviewRightHeaderActions.d.ts +0 -2
- package/esm/ui/App/DockviewRightHeaderActions.js +0 -100
- package/esm/ui/App/DrawerWidgetSelector.d.ts +0 -5
- package/esm/ui/App/DrawerWidgetSelector.js +0 -47
- package/esm/ui/App/JBrowseViewPanel.d.ts +0 -8
- package/esm/ui/App/JBrowseViewPanel.js +0 -40
- package/esm/ui/App/JBrowseViewTab.d.ts +0 -8
- package/esm/ui/App/JBrowseViewTab.js +0 -97
- package/esm/ui/App/ModalWidget.d.ts +0 -6
- package/esm/ui/App/ModalWidget.js +0 -48
- package/esm/ui/App/TiledViewsContainer.d.ts +0 -6
- package/esm/ui/App/TiledViewsContainer.js +0 -366
- package/esm/ui/App/dockviewUtils.d.ts +0 -46
- package/esm/ui/App/dockviewUtils.js +0 -55
package/esm/ui/App/AppFab.js
CHANGED
|
@@ -1,26 +1,33 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { FAB_Z_INDEX } from '@jbrowse/core/ui/zIndexes';
|
|
2
3
|
import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
3
4
|
import LaunchIcon from '@mui/icons-material/Launch';
|
|
4
5
|
import { Fab, Tooltip } from '@mui/material';
|
|
5
6
|
import { observer } from 'mobx-react';
|
|
7
|
+
// `absolute`, against the app root, rather than the `fixed` this used to
|
|
8
|
+
// carry. Fixed measures against the window, and the app root is only the
|
|
9
|
+
// window in a full-window app: under `--jbrowse-app-height` the app is a box
|
|
10
|
+
// somewhere on a host's page (see react-app's fit-to-container example), and
|
|
11
|
+
// this button was pinned to the page's corner instead of the app's. It is the
|
|
12
|
+
// only way back from a minimized drawer, so it cannot be somewhere else on the
|
|
13
|
+
// page.
|
|
6
14
|
const useStyles = makeStyles()(theme => ({
|
|
7
|
-
|
|
8
|
-
zIndex:
|
|
9
|
-
position: '
|
|
15
|
+
fab: {
|
|
16
|
+
zIndex: FAB_Z_INDEX,
|
|
17
|
+
position: 'absolute',
|
|
10
18
|
bottom: theme.spacing(2),
|
|
19
|
+
},
|
|
20
|
+
left: {
|
|
11
21
|
left: theme.spacing(2),
|
|
12
22
|
},
|
|
13
23
|
right: {
|
|
14
|
-
zIndex: 10000,
|
|
15
|
-
position: 'fixed',
|
|
16
|
-
bottom: theme.spacing(2),
|
|
17
24
|
right: theme.spacing(2),
|
|
18
25
|
},
|
|
19
26
|
}));
|
|
20
27
|
const AppFab = observer(function AppFab({ session, }) {
|
|
21
28
|
const { minimized, activeWidgets, drawerPosition } = session;
|
|
22
|
-
const { classes } = useStyles();
|
|
23
|
-
return activeWidgets.size > 0 && minimized ? (_jsx(Tooltip, { title: "Open drawer widget", children: _jsx(Fab, { className: drawerPosition === 'right' ? classes.right : classes.left, color: "primary", "data-testid": "drawer-maximize", onClick: () => {
|
|
29
|
+
const { classes, cx } = useStyles();
|
|
30
|
+
return activeWidgets.size > 0 && minimized ? (_jsx(Tooltip, { title: "Open drawer widget", children: _jsx(Fab, { className: cx(classes.fab, drawerPosition === 'right' ? classes.right : classes.left), color: "primary", "data-testid": "drawer-maximize", onClick: () => {
|
|
24
31
|
session.showWidgetDrawer();
|
|
25
32
|
}, children: _jsx(LaunchIcon, {}) }) })) : null;
|
|
26
33
|
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { AppSession } from './types.ts';
|
|
2
|
+
/**
|
|
3
|
+
* One element that says whether the whole app has finished.
|
|
4
|
+
*
|
|
5
|
+
* `[data-app-phase="ready"]` is the entire readiness contract for anything
|
|
6
|
+
* driving JBrowse from outside — a screenshot tool, a test, an agent. Wait for
|
|
7
|
+
* that selector and you are done; there is no chain to assemble and no
|
|
8
|
+
* per-display census to take.
|
|
9
|
+
*
|
|
10
|
+
* Why it exists when `data-view-phase` and `data-display-phase` already do:
|
|
11
|
+
* those are per-element and NEGATIVE. Asking them "is everything finished"
|
|
12
|
+
* means asserting that no element carries the loading value, which is equally
|
|
13
|
+
* true of an app that has not started — and the gap is real, measured at about
|
|
14
|
+
* a second on a two-track session. A positive attribute cannot be satisfied
|
|
15
|
+
* early, because something has to render it.
|
|
16
|
+
*
|
|
17
|
+
* Its own component, and `hidden`, for two reasons: an observer here subscribes
|
|
18
|
+
* to every view's phase without re-rendering the app shell around it, and a
|
|
19
|
+
* marker that is never drawn cannot be mistaken for UI or shift a layout. It is
|
|
20
|
+
* still found by `querySelector`, which is what reads it.
|
|
21
|
+
*
|
|
22
|
+
* **What it is silent about**: a display in a TERMINAL state. `error` is a
|
|
23
|
+
* finished state, so this reads `ready` over a display whose fetch failed —
|
|
24
|
+
* correctly, since nothing is still working. A capture wants more than that: it
|
|
25
|
+
* wants a picture, and an error banner is not one. `waitForDisplaysDone` after
|
|
26
|
+
* this is what draws that line, keying on the `data-display-drawn` the two
|
|
27
|
+
* comparative canvases publish from their stricter `settled` gate (see
|
|
28
|
+
* `comparativeReadiness` in `@jbrowse/synteny-core`, which holds both answers
|
|
29
|
+
* and says why an error separates them). Both harnesses do it in that order.
|
|
30
|
+
*/
|
|
31
|
+
declare const AppReadyMarker: ({ session, }: {
|
|
32
|
+
session: AppSession;
|
|
33
|
+
}) => import("react").JSX.Element;
|
|
34
|
+
export default AppReadyMarker;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { observer } from 'mobx-react';
|
|
3
|
+
function containerLoading(container) {
|
|
4
|
+
return (container.tracks ?? []).some(track => (track.displays ?? []).some(d => d.displayPhase === 'loading'));
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Is anything in this session still working?
|
|
8
|
+
*
|
|
9
|
+
* The same two facts the per-element attributes publish — a view still
|
|
10
|
+
* resolving its assembly, a display still in its own fetch — reduced to one
|
|
11
|
+
* answer for the whole app. Duck-typed rather than imported: every view type
|
|
12
|
+
* would otherwise have to be a dependency of the app shell.
|
|
13
|
+
*/
|
|
14
|
+
function anythingLoading(views) {
|
|
15
|
+
return views.some(view => view.showLoading === true ||
|
|
16
|
+
view.initialized === false ||
|
|
17
|
+
containerLoading(view) ||
|
|
18
|
+
// A view whose tracks hang off something else — the synteny view's are on
|
|
19
|
+
// its levels, one list per band. `view.tracks` is empty there, so without
|
|
20
|
+
// this a stack of ribbons still fetching reads as idle.
|
|
21
|
+
(view.trackContainers ?? []).some(containerLoading) ||
|
|
22
|
+
anythingLoading(view.views ?? []));
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* One element that says whether the whole app has finished.
|
|
26
|
+
*
|
|
27
|
+
* `[data-app-phase="ready"]` is the entire readiness contract for anything
|
|
28
|
+
* driving JBrowse from outside — a screenshot tool, a test, an agent. Wait for
|
|
29
|
+
* that selector and you are done; there is no chain to assemble and no
|
|
30
|
+
* per-display census to take.
|
|
31
|
+
*
|
|
32
|
+
* Why it exists when `data-view-phase` and `data-display-phase` already do:
|
|
33
|
+
* those are per-element and NEGATIVE. Asking them "is everything finished"
|
|
34
|
+
* means asserting that no element carries the loading value, which is equally
|
|
35
|
+
* true of an app that has not started — and the gap is real, measured at about
|
|
36
|
+
* a second on a two-track session. A positive attribute cannot be satisfied
|
|
37
|
+
* early, because something has to render it.
|
|
38
|
+
*
|
|
39
|
+
* Its own component, and `hidden`, for two reasons: an observer here subscribes
|
|
40
|
+
* to every view's phase without re-rendering the app shell around it, and a
|
|
41
|
+
* marker that is never drawn cannot be mistaken for UI or shift a layout. It is
|
|
42
|
+
* still found by `querySelector`, which is what reads it.
|
|
43
|
+
*
|
|
44
|
+
* **What it is silent about**: a display in a TERMINAL state. `error` is a
|
|
45
|
+
* finished state, so this reads `ready` over a display whose fetch failed —
|
|
46
|
+
* correctly, since nothing is still working. A capture wants more than that: it
|
|
47
|
+
* wants a picture, and an error banner is not one. `waitForDisplaysDone` after
|
|
48
|
+
* this is what draws that line, keying on the `data-display-drawn` the two
|
|
49
|
+
* comparative canvases publish from their stricter `settled` gate (see
|
|
50
|
+
* `comparativeReadiness` in `@jbrowse/synteny-core`, which holds both answers
|
|
51
|
+
* and says why an error separates them). Both harnesses do it in that order.
|
|
52
|
+
*/
|
|
53
|
+
const AppReadyMarker = observer(function AppReadyMarker({ session, }) {
|
|
54
|
+
return (_jsx("span", { hidden: true, "data-testid": "app-ready-marker", "data-app-phase": anythingLoading(session.views) ? 'loading' : 'ready' }));
|
|
55
|
+
});
|
|
56
|
+
export default AppReadyMarker;
|
|
@@ -1,18 +1,6 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { SnackbarMessage } from '@jbrowse/core/ui/SnackbarModel';
|
|
3
|
-
import type { SessionWithDrawerWidgets } from '@jbrowse/core/util';
|
|
4
|
-
interface Menu {
|
|
5
|
-
label: string;
|
|
6
|
-
menuItems: JBMenuItem[] | (() => JBMenuItem[]);
|
|
7
|
-
}
|
|
8
|
-
type AppSession = SessionWithDrawerWidgets & {
|
|
9
|
-
menus: () => Menu[];
|
|
10
|
-
snackbarMessages: SnackbarMessage[];
|
|
11
|
-
renameCurrentSession: (arg: string) => void;
|
|
12
|
-
popSnackbarMessage: () => unknown;
|
|
13
|
-
};
|
|
1
|
+
import type { AppSession } from './types.ts';
|
|
14
2
|
declare const AppToolbar: ({ session, HeaderButtons, }: {
|
|
15
3
|
HeaderButtons?: React.ReactElement;
|
|
16
4
|
session: AppSession;
|
|
17
|
-
}) => import("react
|
|
5
|
+
}) => import("react").JSX.Element;
|
|
18
6
|
export default AppToolbar;
|
package/esm/ui/App/AppToolbar.js
CHANGED
|
@@ -21,39 +21,38 @@ const useStyles = makeStyles()(theme => ({
|
|
|
21
21
|
borderColor: theme.palette.secondary.main,
|
|
22
22
|
backgroundColor: theme.palette.primary.light,
|
|
23
23
|
},
|
|
24
|
+
logo: {
|
|
25
|
+
// stretch to the toolbar height so the logo's height follows the bar
|
|
26
|
+
// rather than a hardcoded pixel value
|
|
27
|
+
alignSelf: 'stretch',
|
|
28
|
+
display: 'flex',
|
|
29
|
+
alignItems: 'center',
|
|
30
|
+
// autofit any logo (custom <img> or the default svg): full toolbar height
|
|
31
|
+
// with auto width preserves aspect ratio, maxWidth caps horizontal room
|
|
32
|
+
'& img, & svg': {
|
|
33
|
+
height: '100%',
|
|
34
|
+
width: 'auto',
|
|
35
|
+
maxWidth: 150,
|
|
36
|
+
objectFit: 'contain',
|
|
37
|
+
},
|
|
38
|
+
},
|
|
24
39
|
}));
|
|
25
|
-
function wrapMenuItems(items, session) {
|
|
26
|
-
return items.map(item => ({
|
|
27
|
-
...item,
|
|
28
|
-
...('onClick' in item
|
|
29
|
-
? {
|
|
30
|
-
onClick: () => {
|
|
31
|
-
item.onClick(session);
|
|
32
|
-
},
|
|
33
|
-
}
|
|
34
|
-
: {}),
|
|
35
|
-
...('subMenu' in item
|
|
36
|
-
? { subMenu: wrapMenuItems(item.subMenu, session) }
|
|
37
|
-
: {}),
|
|
38
|
-
}));
|
|
39
|
-
}
|
|
40
40
|
const AppToolbar = observer(function AppToolbar({ session, HeaderButtons = _jsx("div", {}), }) {
|
|
41
41
|
const { classes } = useStyles();
|
|
42
42
|
const { name, menus } = session;
|
|
43
|
-
return (_jsxs(Toolbar, { children: [menus().map(menu => (_jsx(DropDownMenu, { menuTitle: menu.label, menuItems:
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
43
|
+
return (_jsxs(Toolbar, { children: [menus().map(menu => (_jsx(DropDownMenu, { menuTitle: menu.label, menuItems: menu.menuItems,
|
|
44
|
+
// a root model's menu items take the session as their argument, and
|
|
45
|
+
// the renderer decides how to invoke onClick — so this is the whole
|
|
46
|
+
// binding. It used to be a recursive rewrite of every row of every
|
|
47
|
+
// menu, rebuilt on each open, to arrive at the same call
|
|
48
|
+
onMenuItemClick: callback => {
|
|
49
|
+
callback(session);
|
|
48
50
|
} }, menu.label))), _jsx("div", { className: classes.grow }), _jsx(Tooltip, { title: "Rename session", arrow: true, children: _jsx(EditableTypography, { value: name, variant: "body1", classes: {
|
|
49
51
|
inputBase: classes.inputBase,
|
|
50
52
|
inputRoot: classes.inputRoot,
|
|
51
53
|
inputFocused: classes.inputFocused,
|
|
52
54
|
}, setValue: newName => {
|
|
53
55
|
session.renameCurrentSession(newName);
|
|
54
|
-
} }) }), HeaderButtons, _jsx("div", { className: classes.grow }), _jsx("div", {
|
|
55
|
-
width: 150,
|
|
56
|
-
maxHeight: 48,
|
|
57
|
-
}, children: _jsx(AppLogo, { session: session }) })] }));
|
|
56
|
+
} }) }), HeaderButtons, _jsx("div", { className: classes.grow }), _jsx("div", { className: classes.logo, children: _jsx(AppLogo, { session: session }) })] }));
|
|
58
57
|
});
|
|
59
58
|
export default AppToolbar;
|
|
@@ -1,12 +1,6 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { AbstractViewContainer, SessionWithFocusedViewAndDrawerWidgets } from '@jbrowse/core/util';
|
|
3
|
-
type SessionType = SessionWithFocusedViewAndDrawerWidgets & AbstractViewContainer & {
|
|
4
|
-
renameCurrentSession: (arg: string) => void;
|
|
5
|
-
snackbarMessages: SnackbarMessage[];
|
|
6
|
-
popSnackbarMessage: () => unknown;
|
|
7
|
-
};
|
|
1
|
+
import type { SessionWithFocusedViewAndDrawerWidgets } from '@jbrowse/core/util';
|
|
8
2
|
interface Props {
|
|
9
|
-
session:
|
|
3
|
+
session: SessionWithFocusedViewAndDrawerWidgets;
|
|
10
4
|
}
|
|
11
|
-
declare const ClassicViewsContainer: ({ session, }: Props) => import("react
|
|
5
|
+
declare const ClassicViewsContainer: ({ session, }: Props) => import("react").JSX.Element;
|
|
12
6
|
export default ClassicViewsContainer;
|
|
@@ -1,21 +1,22 @@
|
|
|
1
|
-
import { jsx as _jsx
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { persistentScrollbarStyle } from '@jbrowse/core/ui/persistentScrollbarStyle';
|
|
3
|
+
import { useScrollPortHeightVar } from '@jbrowse/core/util/hooks';
|
|
2
4
|
import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
3
5
|
import { observer } from 'mobx-react';
|
|
4
|
-
import
|
|
5
|
-
const useStyles = makeStyles()({
|
|
6
|
+
import ViewStack from './ViewStack.js';
|
|
7
|
+
const useStyles = makeStyles()(theme => ({
|
|
6
8
|
container: {
|
|
7
9
|
height: '100%',
|
|
8
10
|
width: '100%',
|
|
9
11
|
gridRow: 'components',
|
|
10
12
|
overflowY: 'auto',
|
|
13
|
+
...persistentScrollbarStyle(theme),
|
|
11
14
|
},
|
|
12
|
-
|
|
13
|
-
height: 300,
|
|
14
|
-
},
|
|
15
|
-
});
|
|
15
|
+
}));
|
|
16
16
|
const ClassicViewsContainer = observer(function ClassicViewsContainer({ session, }) {
|
|
17
17
|
const { classes } = useStyles();
|
|
18
18
|
const { views } = session;
|
|
19
|
-
|
|
19
|
+
const ref = useScrollPortHeightVar();
|
|
20
|
+
return (_jsx("div", { ref: ref, className: classes.container, children: _jsx(ViewStack, { views: views, session: session }) }));
|
|
20
21
|
});
|
|
21
22
|
export default ClassicViewsContainer;
|
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
import type { AbstractSessionModel } from '@jbrowse/core/util';
|
|
2
|
+
/**
|
|
3
|
+
* The session's dialog, and the boundary that keeps a dialog that throws from
|
|
4
|
+
* being an application-wide failure.
|
|
5
|
+
*
|
|
6
|
+
* `core/ui/Dialog` already wraps its own CHILDREN, which covers a dialog body
|
|
7
|
+
* that throws. It cannot cover the dialog component's own render, and that is
|
|
8
|
+
* where the reachable case is: a launch dialog resolves its source with
|
|
9
|
+
* `getSession` / `getContainingView` off a track, and "Replace current view"
|
|
10
|
+
* destroys the view that track lives in. This queue renders under `App`, above
|
|
11
|
+
* every per-view boundary, so without this the next one up is the product's —
|
|
12
|
+
* jbrowse-web's fatal-error dialog, which takes every view the user had open.
|
|
13
|
+
* ADR-069, and `cancer_sv/multihop_split_view` is the figure it took.
|
|
14
|
+
*
|
|
15
|
+
* Keyed on the component so the queue advancing to a different dialog clears a
|
|
16
|
+
* banner belonging to the one before it.
|
|
17
|
+
*/
|
|
2
18
|
declare const DialogQueue: ({ session, }: {
|
|
3
19
|
session: AbstractSessionModel;
|
|
4
|
-
}) => import("react
|
|
20
|
+
}) => import("react").JSX.Element | null;
|
|
5
21
|
export default DialogQueue;
|
|
@@ -1,8 +1,37 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { Suspense } from 'react';
|
|
3
|
+
import { Dialog, ErrorMessage } from '@jbrowse/core/ui';
|
|
4
|
+
import { ErrorBoundary } from '@jbrowse/core/ui/ErrorBoundary';
|
|
5
|
+
import { DialogContent } from '@mui/material';
|
|
3
6
|
import { observer } from 'mobx-react';
|
|
7
|
+
// `removeActiveDialog` is BaseSession's, and every product session composes it,
|
|
8
|
+
// but `AbstractSessionModel` does not declare it — so it is asked for rather
|
|
9
|
+
// than assumed. A session without it leaves the fallback's close button doing
|
|
10
|
+
// nothing, which is still better than the page it replaces.
|
|
11
|
+
function dismissActiveDialog(session) {
|
|
12
|
+
;
|
|
13
|
+
session.removeActiveDialog?.();
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The session's dialog, and the boundary that keeps a dialog that throws from
|
|
17
|
+
* being an application-wide failure.
|
|
18
|
+
*
|
|
19
|
+
* `core/ui/Dialog` already wraps its own CHILDREN, which covers a dialog body
|
|
20
|
+
* that throws. It cannot cover the dialog component's own render, and that is
|
|
21
|
+
* where the reachable case is: a launch dialog resolves its source with
|
|
22
|
+
* `getSession` / `getContainingView` off a track, and "Replace current view"
|
|
23
|
+
* destroys the view that track lives in. This queue renders under `App`, above
|
|
24
|
+
* every per-view boundary, so without this the next one up is the product's —
|
|
25
|
+
* jbrowse-web's fatal-error dialog, which takes every view the user had open.
|
|
26
|
+
* ADR-069, and `cancer_sv/multihop_split_view` is the figure it took.
|
|
27
|
+
*
|
|
28
|
+
* Keyed on the component so the queue advancing to a different dialog clears a
|
|
29
|
+
* banner belonging to the one before it.
|
|
30
|
+
*/
|
|
4
31
|
const DialogQueue = observer(function DialogQueue({ session, }) {
|
|
5
32
|
const { DialogComponent, DialogProps } = session;
|
|
6
|
-
return DialogComponent ? (_jsx(
|
|
33
|
+
return DialogComponent ? (_jsx(ErrorBoundary, { resetKeys: [DialogComponent], FallbackComponent: ({ error }) => (_jsx(Dialog, { open: true, title: "Error", onClose: () => {
|
|
34
|
+
dismissActiveDialog(session);
|
|
35
|
+
}, children: _jsx(DialogContent, { children: _jsx(ErrorMessage, { error: error }) }) })), children: _jsx(Suspense, { fallback: null, children: _jsx(DialogComponent, { ...DialogProps }) }) })) : null;
|
|
7
36
|
});
|
|
8
37
|
export default DialogQueue;
|
package/esm/ui/App/Drawer.d.ts
CHANGED
|
@@ -2,5 +2,5 @@ import type { SessionWithFocusedViewAndDrawerWidgets } from '@jbrowse/core/util/
|
|
|
2
2
|
declare const Drawer: ({ children, session, }: {
|
|
3
3
|
children: React.ReactNode;
|
|
4
4
|
session: SessionWithFocusedViewAndDrawerWidgets;
|
|
5
|
-
}) => import("react
|
|
5
|
+
}) => import("react").JSX.Element;
|
|
6
6
|
export default Drawer;
|
package/esm/ui/App/Drawer.js
CHANGED
|
@@ -1,45 +1,16 @@
|
|
|
1
|
-
import { jsx as _jsx
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import { Paper } from '@mui/material';
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useRef } from 'react';
|
|
3
|
+
import { useFocusOnInteraction } from '@jbrowse/core/util/hooks';
|
|
4
|
+
import { Drawer as DrawerShell } from '@jbrowse/product-core';
|
|
6
5
|
import { observer } from 'mobx-react';
|
|
7
|
-
const useStyles = makeStyles()(theme => ({
|
|
8
|
-
paper: {
|
|
9
|
-
overflowY: 'auto',
|
|
10
|
-
height: '100%',
|
|
11
|
-
position: 'relative',
|
|
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
6
|
const Drawer = observer(function Drawer({ children, session, }) {
|
|
24
|
-
const { drawerPosition, drawerWidth } = session;
|
|
25
|
-
const { classes } = useStyles();
|
|
26
7
|
const ref = useRef(null);
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
if (visibleWidgetId) {
|
|
32
|
-
session.setFocusedViewId(visibleWidgetId);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
8
|
+
useFocusOnInteraction(ref, () => {
|
|
9
|
+
const visibleWidgetId = session.visibleWidget?.view?.id;
|
|
10
|
+
if (visibleWidgetId) {
|
|
11
|
+
session.setFocusedViewId(visibleWidgetId);
|
|
35
12
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
return () => {
|
|
39
|
-
document.removeEventListener('mousedown', handleSelectView);
|
|
40
|
-
document.removeEventListener('keydown', handleSelectView);
|
|
41
|
-
};
|
|
42
|
-
}, [session]);
|
|
43
|
-
return (_jsxs(Paper, { ref: ref, className: classes.paper, elevation: 16, square: true, children: [drawerPosition === 'right' ? (_jsx(ResizeHandle, { onDrag: session.resizeDrawer, className: classes.resizeHandle, vertical: true })) : null, children, drawerPosition === 'left' ? (_jsx(ResizeHandle, { onDrag: session.resizeDrawer, className: classes.resizeHandle, style: { left: drawerWidth }, vertical: true })) : null] }));
|
|
13
|
+
});
|
|
14
|
+
return (_jsx(DrawerShell, { session: session, ref: ref, children: children }));
|
|
44
15
|
});
|
|
45
16
|
export default Drawer;
|
|
@@ -1,5 +1 @@
|
|
|
1
|
-
|
|
2
|
-
declare const DrawerControls: ({ session, }: {
|
|
3
|
-
session: SessionWithFocusedViewAndDrawerWidgets;
|
|
4
|
-
}) => import("react/jsx-runtime").JSX.Element;
|
|
5
|
-
export default DrawerControls;
|
|
1
|
+
export { DrawerControls as default } from '@jbrowse/product-core';
|
|
@@ -1,25 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { useState } from 'react';
|
|
3
|
-
import CloseIcon from '@mui/icons-material/Close';
|
|
4
|
-
import MinimizeIcon from '@mui/icons-material/Minimize';
|
|
5
|
-
import MoreVertIcon from '@mui/icons-material/MoreVert';
|
|
6
|
-
import { IconButton, Menu, MenuItem, Tooltip } from '@mui/material';
|
|
7
|
-
import { observer } from 'mobx-react';
|
|
8
|
-
const DrawerControls = observer(function DrawerControls({ session, }) {
|
|
9
|
-
const [anchorEl, setAnchorEl] = useState(null);
|
|
10
|
-
const { drawerPosition, visibleWidget } = session;
|
|
11
|
-
return (_jsxs(_Fragment, { children: [_jsx(IconButton, { color: "inherit", onClick: event => {
|
|
12
|
-
setAnchorEl(event.currentTarget);
|
|
13
|
-
}, children: _jsx(MoreVertIcon, {}) }), _jsx(Tooltip, { title: "Minimize drawer", children: _jsx(IconButton, { "data-testid": "drawer-minimize", color: "inherit", onClick: () => {
|
|
14
|
-
session.notify(`Drawer minimized, click button on ${drawerPosition} side of screen to re-open`, 'info');
|
|
15
|
-
session.minimizeWidgetDrawer();
|
|
16
|
-
}, children: _jsx(MinimizeIcon, {}) }) }), _jsx(Tooltip, { title: "Close drawer", children: _jsx(IconButton, { color: "inherit", onClick: () => {
|
|
17
|
-
session.hideWidget(visibleWidget);
|
|
18
|
-
}, children: _jsx(CloseIcon, {}) }) }), _jsx(Menu, { anchorEl: anchorEl, open: Boolean(anchorEl), onClose: () => {
|
|
19
|
-
setAnchorEl(null);
|
|
20
|
-
}, children: ['left', 'right'].map(option => (_jsx(MenuItem, { selected: drawerPosition === 'option', onClick: () => {
|
|
21
|
-
session.setDrawerPosition(option);
|
|
22
|
-
setAnchorEl(null);
|
|
23
|
-
}, children: option }, option))) })] }));
|
|
24
|
-
});
|
|
25
|
-
export default DrawerControls;
|
|
1
|
+
export { DrawerControls as default } from '@jbrowse/product-core';
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { SessionWithFocusedViewAndDrawerWidgets } from '@jbrowse/core/util/types';
|
|
2
|
-
declare const DrawerHeader: ({ session, setToolbarHeight,
|
|
2
|
+
declare const DrawerHeader: ({ session, setToolbarHeight, }: {
|
|
3
3
|
session: SessionWithFocusedViewAndDrawerWidgets;
|
|
4
4
|
setToolbarHeight: (arg: number) => void;
|
|
5
|
-
|
|
6
|
-
}) => import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
}) => import("react").JSX.Element;
|
|
7
6
|
export default DrawerHeader;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Suspense, lazy } from 'react';
|
|
2
|
+
import { Suspense, lazy, useCallback } from 'react';
|
|
3
3
|
import { getEnv } from '@jbrowse/core/util';
|
|
4
4
|
import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
5
|
+
import { DrawerWidgetSelector } from '@jbrowse/product-core';
|
|
5
6
|
import LaunchIcon from '@mui/icons-material/Launch';
|
|
6
7
|
import { AppBar, IconButton, Toolbar, Tooltip } from '@mui/material';
|
|
7
8
|
import { observer } from 'mobx-react';
|
|
8
|
-
import DrawerControls from
|
|
9
|
-
|
|
10
|
-
const DrawerHeaderHelpButton = lazy(() => import("./DrawerHeaderHelpButton.js"));
|
|
9
|
+
import DrawerControls from './DrawerControls.js';
|
|
10
|
+
const DrawerHeaderHelpButton = lazy(() => import('./DrawerHeaderHelpButton.js'));
|
|
11
11
|
const useStyles = makeStyles()(theme => ({
|
|
12
12
|
spacer: {
|
|
13
13
|
flexGrow: 1,
|
|
@@ -19,7 +19,7 @@ const useStyles = makeStyles()(theme => ({
|
|
|
19
19
|
background: theme.palette.secondary.dark,
|
|
20
20
|
},
|
|
21
21
|
}));
|
|
22
|
-
const DrawerHeader = observer(function DrawerHeader({ session, setToolbarHeight,
|
|
22
|
+
const DrawerHeader = observer(function DrawerHeader({ session, setToolbarHeight, }) {
|
|
23
23
|
const { classes } = useStyles();
|
|
24
24
|
const focusedViewId = session.focusedViewId;
|
|
25
25
|
const { visibleWidget } = session;
|
|
@@ -28,13 +28,27 @@ const DrawerHeader = observer(function DrawerHeader({ session, setToolbarHeight,
|
|
|
28
28
|
const widgetType = visibleWidget
|
|
29
29
|
? pluginManager.getWidgetType(visibleWidget.type)
|
|
30
30
|
: undefined;
|
|
31
|
-
const { helpText } = widgetType
|
|
31
|
+
const { helpText } = widgetType ?? {};
|
|
32
|
+
// Measured, and re-measured: the toolbar's height is the room a virtualized
|
|
33
|
+
// widget subtracts from the box it is given, and it changes without this
|
|
34
|
+
// component re-rendering -- MUI's Toolbar is 56px under the `sm` breakpoint
|
|
35
|
+
// and 64 above it, and grows again with the root font size. Read once at
|
|
36
|
+
// mount, a widget's list was that much too tall for the rest of the session.
|
|
37
|
+
const appBarRef = useCallback((node) => {
|
|
38
|
+
const publish = () => {
|
|
39
|
+
setToolbarHeight(node.getBoundingClientRect().height);
|
|
40
|
+
};
|
|
41
|
+
publish();
|
|
42
|
+
const observer = new ResizeObserver(publish);
|
|
43
|
+
observer.observe(node);
|
|
44
|
+
return () => {
|
|
45
|
+
observer.disconnect();
|
|
46
|
+
};
|
|
47
|
+
}, [setToolbarHeight]);
|
|
32
48
|
return (_jsx(AppBar, { position: "sticky", className: focusedViewId === viewWidgetId
|
|
33
49
|
? classes.headerFocused
|
|
34
|
-
: classes.headerUnfocused, ref:
|
|
35
|
-
|
|
36
|
-
}, children: _jsxs(Toolbar, { disableGutters: true, children: [_jsx(DrawerWidgetSelector, { session: session }), _jsx(Tooltip, { title: "Open drawer in dialog", children: _jsx(IconButton, { color: "inherit", onClick: () => {
|
|
37
|
-
onPopoutDrawer();
|
|
50
|
+
: classes.headerUnfocused, ref: appBarRef, children: _jsxs(Toolbar, { disableGutters: true, children: [_jsx(DrawerWidgetSelector, { session: session }), _jsx(Tooltip, { title: "Open drawer in dialog", children: _jsx(IconButton, { color: "inherit", "data-testid": "drawer-popout", onClick: () => {
|
|
51
|
+
session.popoutWidget();
|
|
38
52
|
}, 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 })] }) }));
|
|
39
53
|
});
|
|
40
54
|
export default DrawerHeader;
|
|
@@ -2,5 +2,5 @@ import type { SessionWithFocusedViewAndDrawerWidgets } from '@jbrowse/core/util/
|
|
|
2
2
|
declare const DrawerHeaderHelpButton: ({ session, helpText, }: {
|
|
3
3
|
session: SessionWithFocusedViewAndDrawerWidgets;
|
|
4
4
|
helpText: React.ReactNode;
|
|
5
|
-
}) => import("react
|
|
5
|
+
}) => import("react").JSX.Element;
|
|
6
6
|
export default DrawerHeaderHelpButton;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { lazy } from 'react';
|
|
3
|
-
import
|
|
3
|
+
import HelpOutlined from '@mui/icons-material/HelpOutlined';
|
|
4
4
|
import { IconButton, Tooltip } from '@mui/material';
|
|
5
5
|
import { observer } from 'mobx-react';
|
|
6
|
-
const DrawerHeaderHelpDialog = lazy(() => import(
|
|
6
|
+
const DrawerHeaderHelpDialog = lazy(() => import('./DrawerHeaderHelpDialog.js'));
|
|
7
7
|
const DrawerHeaderHelpButton = observer(function DrawerHeaderHelpButton({ session, helpText, }) {
|
|
8
8
|
return (_jsx(Tooltip, { title: "Help", children: _jsx(IconButton, { color: "inherit", onClick: () => {
|
|
9
9
|
session.queueDialog(handleClose => [
|
|
@@ -13,6 +13,6 @@ const DrawerHeaderHelpButton = observer(function DrawerHeaderHelpButton({ sessio
|
|
|
13
13
|
helpText,
|
|
14
14
|
},
|
|
15
15
|
]);
|
|
16
|
-
}, children: _jsx(
|
|
16
|
+
}, children: _jsx(HelpOutlined, {}) }) }));
|
|
17
17
|
});
|
|
18
18
|
export default DrawerHeaderHelpButton;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export default function DrawerHeaderHelpDialog({ onClose, helpText, }: {
|
|
2
|
-
onClose: (
|
|
2
|
+
onClose: () => void;
|
|
3
3
|
helpText: React.ReactNode;
|
|
4
|
-
}): import("react
|
|
4
|
+
}): import("react").JSX.Element;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import
|
|
2
|
+
import InfoDialog from '@jbrowse/core/ui/InfoDialog';
|
|
3
3
|
import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
4
|
-
import { DialogContent } from '@mui/material';
|
|
5
4
|
const useStyles = makeStyles()({
|
|
6
5
|
max: {
|
|
7
6
|
minWidth: '40em',
|
|
@@ -9,7 +8,7 @@ const useStyles = makeStyles()({
|
|
|
9
8
|
});
|
|
10
9
|
export default function DrawerHeaderHelpDialog({ onClose, helpText, }) {
|
|
11
10
|
const { classes } = useStyles();
|
|
12
|
-
return (_jsx(
|
|
11
|
+
return (_jsx(InfoDialog, { open: true, onClose: onClose, title: "Help", maxWidth: "xl", onClick: e => {
|
|
13
12
|
e.stopPropagation();
|
|
14
|
-
}, children: _jsx(
|
|
13
|
+
}, children: _jsx("div", { className: classes.max, children: helpText }) }));
|
|
15
14
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { SessionWithFocusedViewAndDrawerWidgets } from '@jbrowse/core/util/types';
|
|
2
2
|
declare const DrawerWidget: ({ session, }: {
|
|
3
3
|
session: SessionWithFocusedViewAndDrawerWidgets;
|
|
4
|
-
}) => import("react
|
|
4
|
+
}) => import("react").JSX.Element;
|
|
5
5
|
export default DrawerWidget;
|
|
@@ -1,27 +1,15 @@
|
|
|
1
|
-
import { jsx as _jsx,
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { ErrorBoundary } from '@jbrowse/core/ui/ErrorBoundary';
|
|
5
|
-
import { getEnv } from '@jbrowse/core/util';
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { WidgetBody } from '@jbrowse/product-core';
|
|
6
4
|
import { observer } from 'mobx-react';
|
|
7
|
-
import Drawer from
|
|
8
|
-
import DrawerHeader from
|
|
9
|
-
const ModalWidget = lazy(() => import("./ModalWidget.js"));
|
|
5
|
+
import Drawer from './Drawer.js';
|
|
6
|
+
import DrawerHeader from './DrawerHeader.js';
|
|
10
7
|
const DrawerWidget = observer(function DrawerWidget({ session, }) {
|
|
11
8
|
const { visibleWidget } = session;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
session,
|
|
16
|
-
model: visibleWidget,
|
|
17
|
-
})
|
|
18
|
-
: null;
|
|
9
|
+
// we track the toolbar height because components that use virtualized
|
|
10
|
+
// height want to be able to fill the contained, minus the toolbar height
|
|
11
|
+
// (the position static/sticky is included in AutoSizer estimates)
|
|
19
12
|
const [toolbarHeight, setToolbarHeight] = useState(0);
|
|
20
|
-
|
|
21
|
-
return (_jsxs(Drawer, { session: session, children: [_jsx(DrawerHeader, { onPopoutDrawer: () => {
|
|
22
|
-
setPopoutDrawer(true);
|
|
23
|
-
}, session: session, setToolbarHeight: setToolbarHeight }), _jsx(Suspense, { fallback: _jsx(LoadingEllipses, {}), children: _jsx(ErrorBoundary, { FallbackComponent: ({ error }) => _jsx(ErrorMessage, { error: error }), children: DrawerComponent ? (popoutDrawer ? (_jsxs(_Fragment, { children: [_jsx("div", { children: "Opened in dialog..." }), _jsx(ModalWidget, { session: session, onClose: () => {
|
|
24
|
-
setPopoutDrawer(false);
|
|
25
|
-
} })] })) : (_jsxs(_Fragment, { children: [_jsx(DrawerComponent, { model: visibleWidget, session: session, toolbarHeight: toolbarHeight }), _jsx("div", { style: { height: 300 } })] }))) : null }) })] }));
|
|
13
|
+
return (_jsxs(Drawer, { session: session, children: [_jsx(DrawerHeader, { session: session, setToolbarHeight: setToolbarHeight }), visibleWidget ? (_jsx(WidgetBody, { session: session, widget: visibleWidget, toolbarHeight: toolbarHeight })) : null] }));
|
|
26
14
|
});
|
|
27
15
|
export default DrawerWidget;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
export default function JBrowseTabMenu({
|
|
2
|
-
isHovered: boolean;
|
|
1
|
+
export default function JBrowseTabMenu({ onRename, onClose, }: {
|
|
3
2
|
onRename: () => void;
|
|
4
3
|
onClose: () => void;
|
|
5
|
-
}): import("react
|
|
4
|
+
}): import("react").JSX.Element;
|