@jbrowse/app-core 2.13.0 → 2.14.0

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 (43) hide show
  1. package/dist/Assemblies/SessionAssembliesMixin.d.ts +2 -2
  2. package/dist/JBrowseConfig/index.js +1 -1
  3. package/dist/JBrowseModel/index.d.ts +2 -2
  4. package/dist/JBrowseModel/index.js +7 -7
  5. package/dist/ui/App/App.js +3 -16
  6. package/dist/ui/App/AppFab.js +3 -1
  7. package/dist/ui/App/AppToolbar.d.ts +2 -2
  8. package/dist/ui/App/Drawer.js +2 -2
  9. package/dist/ui/App/DrawerControls.js +9 -3
  10. package/dist/ui/App/DrawerHeader.js +6 -2
  11. package/dist/ui/App/DrawerWidget.js +6 -2
  12. package/dist/ui/App/DrawerWidgetSelector.js +3 -1
  13. package/dist/ui/App/ModalWidget.js +4 -6
  14. package/dist/ui/App/ViewContainer.js +1 -1
  15. package/dist/ui/App/ViewContainerTitle.js +3 -1
  16. package/dist/ui/App/ViewHeader.js +4 -2
  17. package/dist/ui/App/ViewLauncher.js +9 -4
  18. package/dist/ui/App/ViewMenu.js +18 -11
  19. package/dist/ui/App/ViewPanel.js +5 -1
  20. package/dist/ui/App/ViewsContainer.d.ts +19 -0
  21. package/dist/ui/App/ViewsContainer.js +26 -0
  22. package/esm/Assemblies/SessionAssembliesMixin.d.ts +2 -2
  23. package/esm/JBrowseConfig/index.js +1 -1
  24. package/esm/JBrowseModel/index.d.ts +2 -2
  25. package/esm/JBrowseModel/index.js +7 -7
  26. package/esm/ui/App/App.js +3 -16
  27. package/esm/ui/App/AppFab.js +3 -1
  28. package/esm/ui/App/AppToolbar.d.ts +2 -2
  29. package/esm/ui/App/Drawer.js +2 -2
  30. package/esm/ui/App/DrawerControls.js +9 -3
  31. package/esm/ui/App/DrawerHeader.js +6 -2
  32. package/esm/ui/App/DrawerWidget.js +6 -2
  33. package/esm/ui/App/DrawerWidgetSelector.js +3 -1
  34. package/esm/ui/App/ModalWidget.js +4 -6
  35. package/esm/ui/App/ViewContainer.js +1 -1
  36. package/esm/ui/App/ViewContainerTitle.js +3 -1
  37. package/esm/ui/App/ViewHeader.js +4 -2
  38. package/esm/ui/App/ViewLauncher.js +9 -4
  39. package/esm/ui/App/ViewMenu.js +18 -11
  40. package/esm/ui/App/ViewPanel.js +5 -1
  41. package/esm/ui/App/ViewsContainer.d.ts +19 -0
  42. package/esm/ui/App/ViewsContainer.js +21 -0
  43. package/package.json +4 -4
@@ -37,7 +37,7 @@ export declare function SessionAssembliesMixin(pluginManager: PluginManager, ass
37
37
  /**
38
38
  * #action
39
39
  */
40
- addSessionAssembly(conf: AnyConfiguration): {
40
+ addSessionAssembly(conf: AnyConfiguration): ({
41
41
  [x: string]: any;
42
42
  } & import("mobx-state-tree/dist/internal").NonEmptyObject & {
43
43
  setSubschema(slotName: string, data: Record<string, unknown>): Record<string, unknown> | ({
@@ -70,7 +70,7 @@ export declare function SessionAssembliesMixin(pluginManager: PluginManager, ass
70
70
  defaultValue: string;
71
71
  description: string;
72
72
  };
73
- }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "name">>>;
73
+ }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "name">>>) | undefined;
74
74
  /**
75
75
  * #action
76
76
  */
@@ -127,7 +127,7 @@ function JBrowseConfigF({ pluginManager, assemblyConfigSchema, }) {
127
127
  * #slot
128
128
  */
129
129
  defaultSession: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.frozen(), {
130
- name: `New Session`,
130
+ name: 'New Session',
131
131
  }),
132
132
  });
133
133
  }
@@ -137,7 +137,7 @@ export declare function JBrowseModelF({ pluginManager, assemblyConfigSchema, }:
137
137
  /**
138
138
  * #action
139
139
  */
140
- addAssemblyConf(conf: AnyConfigurationModel): {
140
+ addAssemblyConf(conf: AnyConfigurationModel): ({
141
141
  [x: string]: any;
142
142
  } & import("mobx-state-tree/dist/internal").NonEmptyObject & {
143
143
  setSubschema(slotName: string, data: Record<string, unknown>): Record<string, unknown> | ({
@@ -147,7 +147,7 @@ export declare function JBrowseModelF({ pluginManager, assemblyConfigSchema, }:
147
147
  [x: string]: any;
148
148
  } & import("mobx-state-tree/dist/internal").NonEmptyObject & any & import("mobx-state-tree").IStateTreeNode<import("@jbrowse/core/configuration").AnyConfigurationSchemaType>);
149
149
  } & import("mobx-state-tree").IStateTreeNode<import("@jbrowse/core/configuration").AnyConfigurationSchemaType>);
150
- } & import("mobx-state-tree").IStateTreeNode<import("@jbrowse/core/configuration").AnyConfigurationSchemaType>;
150
+ } & import("mobx-state-tree").IStateTreeNode<import("@jbrowse/core/configuration").AnyConfigurationSchemaType>) | undefined;
151
151
  /**
152
152
  * #action
153
153
  */
@@ -30,7 +30,6 @@ function JBrowseModelF({ pluginManager, assemblyConfigSchema, }) {
30
30
  * #getter
31
31
  */
32
32
  get rpcManager() {
33
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
34
33
  return (0, mobx_state_tree_1.getParent)(self).rpcManager;
35
34
  },
36
35
  }))
@@ -106,7 +105,6 @@ function JBrowseModelF({ pluginManager, assemblyConfigSchema, }) {
106
105
  */
107
106
  addPlugin(pluginDefinition) {
108
107
  self.plugins.push(pluginDefinition);
109
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
110
108
  const rootModel = (0, mobx_state_tree_1.getParent)(self);
111
109
  rootModel.setPluginsUpdated(true);
112
110
  },
@@ -114,20 +112,22 @@ function JBrowseModelF({ pluginManager, assemblyConfigSchema, }) {
114
112
  * #action
115
113
  */
116
114
  removePlugin(pluginDefinition) {
117
- self.plugins = (0, mobx_state_tree_1.cast)(self.plugins.filter(plugin => plugin.url !== pluginDefinition.url ||
115
+ self.plugins = (0, mobx_state_tree_1.cast)(self.plugins.filter(plugin =>
116
+ // @ts-expect-error
117
+ plugin.url !== pluginDefinition.url ||
118
+ // @ts-expect-error
118
119
  plugin.umdUrl !== pluginDefinition.umdUrl ||
120
+ // @ts-expect-error
119
121
  plugin.cjsUrl !== pluginDefinition.cjsUrl ||
122
+ // @ts-expect-error
120
123
  plugin.esmUrl !== pluginDefinition.esmUrl));
121
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
122
124
  (0, mobx_state_tree_1.getParent)(self).setPluginsUpdated(true);
123
125
  },
124
126
  /**
125
127
  * #action
126
128
  */
127
129
  setDefaultSessionConf(sessionConf) {
128
- const newDefault =
129
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
130
- (0, mobx_state_tree_1.getParent)(self).session.name === sessionConf.name
130
+ const newDefault = (0, mobx_state_tree_1.getParent)(self).session.name === sessionConf.name
131
131
  ? (0, mobx_state_tree_1.getSnapshot)(sessionConf)
132
132
  : (0, mobx_1.toJS)(sessionConf);
133
133
  if (!newDefault.name) {
@@ -34,10 +34,9 @@ const mobx_react_1 = require("mobx-react");
34
34
  const Snackbar_1 = __importDefault(require("@jbrowse/core/ui/Snackbar"));
35
35
  // locals
36
36
  const AppToolbar_1 = __importDefault(require("./AppToolbar"));
37
- const ViewLauncher_1 = __importDefault(require("./ViewLauncher"));
38
- const ViewPanel_1 = __importDefault(require("./ViewPanel"));
39
37
  const DialogQueue_1 = __importDefault(require("./DialogQueue"));
40
38
  const AppFab_1 = __importDefault(require("./AppFab"));
39
+ const ViewsContainer_1 = __importDefault(require("./ViewsContainer"));
41
40
  const DrawerWidget = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./DrawerWidget'))));
42
41
  const useStyles = (0, mui_1.makeStyles)()(theme => ({
43
42
  root: {
@@ -52,10 +51,6 @@ const useStyles = (0, mui_1.makeStyles)()(theme => ({
52
51
  gridTemplateRows: '[menubar] min-content [components] auto',
53
52
  height: '100vh',
54
53
  },
55
- viewContainer: {
56
- overflowY: 'auto',
57
- gridRow: 'components',
58
- },
59
54
  appBar: {
60
55
  flexGrow: 1,
61
56
  gridRow: 'menubar',
@@ -66,14 +61,6 @@ const LazyDrawerWidget = (0, mobx_react_1.observer)(function (props) {
66
61
  return (react_1.default.createElement(react_1.Suspense, { fallback: null },
67
62
  react_1.default.createElement(DrawerWidget, { session: session })));
68
63
  });
69
- const ViewContainer = (0, mobx_react_1.observer)(function (props) {
70
- const { session } = props;
71
- const { views } = session;
72
- const { classes } = useStyles();
73
- return (react_1.default.createElement("div", { className: classes.viewContainer },
74
- views.length > 0 ? (views.map(view => (react_1.default.createElement(ViewPanel_1.default, { key: `view-${view.id}`, view: view, session: session })))) : (react_1.default.createElement(ViewLauncher_1.default, { ...props })),
75
- react_1.default.createElement("div", { style: { height: 300 } })));
76
- });
77
64
  const App = (0, mobx_react_1.observer)(function (props) {
78
65
  const { session } = props;
79
66
  const { classes } = useStyles();
@@ -81,13 +68,13 @@ const App = (0, mobx_react_1.observer)(function (props) {
81
68
  const drawerVisible = visibleWidget && !minimized;
82
69
  const d = drawerVisible ? `[drawer] ${drawerWidth}px` : undefined;
83
70
  const grid = drawerPosition === 'right' ? ['[main] 1fr', d] : [d, '[main] 1fr'];
84
- return (react_1.default.createElement("div", { className: classes.root, style: { gridTemplateColumns: grid === null || grid === void 0 ? void 0 : grid.filter(f => !!f).join(' ') } },
71
+ return (react_1.default.createElement("div", { className: classes.root, style: { gridTemplateColumns: grid.filter(f => !!f).join(' ') } },
85
72
  drawerVisible && drawerPosition === 'left' ? (react_1.default.createElement(LazyDrawerWidget, { session: session })) : null,
86
73
  react_1.default.createElement(DialogQueue_1.default, { session: session }),
87
74
  react_1.default.createElement("div", { className: classes.appContainer },
88
75
  react_1.default.createElement(material_1.AppBar, { className: classes.appBar, position: "static" },
89
76
  react_1.default.createElement(AppToolbar_1.default, { ...props })),
90
- react_1.default.createElement(ViewContainer, { ...props })),
77
+ react_1.default.createElement(ViewsContainer_1.default, { ...props })),
91
78
  react_1.default.createElement(AppFab_1.default, { session: session }),
92
79
  drawerVisible && drawerPosition === 'right' ? (react_1.default.createElement(LazyDrawerWidget, { session: session })) : null,
93
80
  react_1.default.createElement(Snackbar_1.default, { session: session })));
@@ -27,7 +27,9 @@ const AppFab = (0, mobx_react_1.observer)(function ({ session, }) {
27
27
  const { minimized, activeWidgets, drawerPosition } = session;
28
28
  const { classes } = useStyles();
29
29
  return activeWidgets.size > 0 && minimized ? (react_1.default.createElement(material_1.Tooltip, { title: "Open drawer widget" },
30
- react_1.default.createElement(material_1.Fab, { className: drawerPosition === 'right' ? classes.right : classes.left, color: "primary", "data-testid": "drawer-maximize", onClick: () => session.showWidgetDrawer() },
30
+ react_1.default.createElement(material_1.Fab, { className: drawerPosition === 'right' ? classes.right : classes.left, color: "primary", "data-testid": "drawer-maximize", onClick: () => {
31
+ session.showWidgetDrawer();
32
+ } },
31
33
  react_1.default.createElement(Launch_1.default, null)))) : null;
32
34
  });
33
35
  exports.default = AppFab;
@@ -3,13 +3,13 @@ import { SessionWithDrawerWidgets } from '@jbrowse/core/util';
3
3
  import { MenuItem as JBMenuItem } from '@jbrowse/core/ui/Menu';
4
4
  import { SnackbarMessage } from '@jbrowse/core/ui/SnackbarModel';
5
5
  type AppSession = SessionWithDrawerWidgets & {
6
- savedSessionNames: string[];
7
6
  menus: {
8
7
  label: string;
9
8
  menuItems: JBMenuItem[];
10
9
  }[];
11
- renameCurrentSession: (arg: string) => void;
10
+ savedSessionNames?: string[];
12
11
  snackbarMessages: SnackbarMessage[];
12
+ renameCurrentSession: (arg: string) => void;
13
13
  popSnackbarMessage: () => unknown;
14
14
  };
15
15
  declare const AppToolbar: ({ session, HeaderButtons, }: {
@@ -54,7 +54,7 @@ const Drawer = (0, mobx_react_1.observer)(function ({ children, session, }) {
54
54
  (0, react_1.useEffect)(() => {
55
55
  function handleSelectView(e) {
56
56
  var _a, _b, _c;
57
- if (e.target instanceof Element && ((_a = ref === null || ref === void 0 ? void 0 : ref.current) === null || _a === void 0 ? void 0 : _a.contains(e.target))) {
57
+ if (e.target instanceof Element && ((_a = ref.current) === null || _a === void 0 ? void 0 : _a.contains(e.target))) {
58
58
  // @ts-ignore
59
59
  const visibleWidgetId = (_c = (_b = session.visibleWidget) === null || _b === void 0 ? void 0 : _b.view) === null || _c === void 0 ? void 0 : _c.id;
60
60
  if (visibleWidgetId) {
@@ -68,7 +68,7 @@ const Drawer = (0, mobx_react_1.observer)(function ({ children, session, }) {
68
68
  document.removeEventListener('mousedown', handleSelectView);
69
69
  document.removeEventListener('keydown', handleSelectView);
70
70
  };
71
- }, [ref, session]);
71
+ }, [session]);
72
72
  return (react_1.default.createElement(material_1.Paper, { ref: ref, className: classes.paper, elevation: 16, square: true },
73
73
  drawerPosition === 'right' ? (react_1.default.createElement(ResizeHandle_1.default, { onDrag: session.resizeDrawer, className: classes.resizeHandle, vertical: true })) : null,
74
74
  children,
@@ -37,7 +37,9 @@ const DrawerControls = (0, mobx_react_1.observer)(function ({ session, }) {
37
37
  const [anchorEl, setAnchorEl] = (0, react_1.useState)(null);
38
38
  const { drawerPosition, visibleWidget } = session;
39
39
  return (react_1.default.createElement(react_1.default.Fragment, null,
40
- react_1.default.createElement(material_1.IconButton, { color: "inherit", onClick: event => setAnchorEl(event.currentTarget) },
40
+ react_1.default.createElement(material_1.IconButton, { color: "inherit", onClick: event => {
41
+ setAnchorEl(event.currentTarget);
42
+ } },
41
43
  react_1.default.createElement(MoreVert_1.default, null)),
42
44
  react_1.default.createElement(material_1.Tooltip, { title: "Minimize drawer" },
43
45
  react_1.default.createElement(material_1.IconButton, { "data-testid": "drawer-minimize", color: "inherit", onClick: () => {
@@ -46,9 +48,13 @@ const DrawerControls = (0, mobx_react_1.observer)(function ({ session, }) {
46
48
  } },
47
49
  react_1.default.createElement(Minimize_1.default, null))),
48
50
  react_1.default.createElement(material_1.Tooltip, { title: "Close drawer" },
49
- react_1.default.createElement(material_1.IconButton, { color: "inherit", onClick: () => session.hideWidget(visibleWidget) },
51
+ react_1.default.createElement(material_1.IconButton, { color: "inherit", onClick: () => {
52
+ session.hideWidget(visibleWidget);
53
+ } },
50
54
  react_1.default.createElement(Close_1.default, null))),
51
- react_1.default.createElement(material_1.Menu, { anchorEl: anchorEl, open: Boolean(anchorEl), onClose: () => setAnchorEl(null) }, ['left', 'right'].map(option => (react_1.default.createElement(material_1.MenuItem, { key: option, selected: drawerPosition === 'option', onClick: () => {
55
+ react_1.default.createElement(material_1.Menu, { anchorEl: anchorEl, open: Boolean(anchorEl), onClose: () => {
56
+ setAnchorEl(null);
57
+ } }, ['left', 'right'].map(option => (react_1.default.createElement(material_1.MenuItem, { key: option, selected: drawerPosition === 'option', onClick: () => {
52
58
  session.setDrawerPosition(option);
53
59
  setAnchorEl(null);
54
60
  } }, option))))));
@@ -31,11 +31,15 @@ const DrawerHeader = (0, mobx_react_1.observer)(function ({ session, setToolbarH
31
31
  const viewWidgetId = (_b = (_a = session.visibleWidget) === null || _a === void 0 ? void 0 : _a.view) === null || _b === void 0 ? void 0 : _b.id;
32
32
  return (react_1.default.createElement(material_1.AppBar, { position: "sticky", className: focusedViewId === viewWidgetId
33
33
  ? classes.headerFocused
34
- : classes.headerUnfocused, ref: ref => setToolbarHeight((ref === null || ref === void 0 ? void 0 : ref.getBoundingClientRect().height) || 0) },
34
+ : classes.headerUnfocused, ref: ref => {
35
+ setToolbarHeight((ref === null || ref === void 0 ? void 0 : ref.getBoundingClientRect().height) || 0);
36
+ } },
35
37
  react_1.default.createElement(material_1.Toolbar, { disableGutters: true },
36
38
  react_1.default.createElement(DrawerWidgetSelector_1.default, { session: session }),
37
39
  react_1.default.createElement(material_1.Tooltip, { title: "Open drawer in dialog" },
38
- react_1.default.createElement(material_1.IconButton, { color: "inherit", onClick: () => onPopoutDrawer() },
40
+ react_1.default.createElement(material_1.IconButton, { color: "inherit", onClick: () => {
41
+ onPopoutDrawer();
42
+ } },
39
43
  react_1.default.createElement(Launch_1.default, null))),
40
44
  react_1.default.createElement("div", { className: classes.spacer }),
41
45
  react_1.default.createElement(DrawerControls_1.default, { session: session }))));
@@ -50,11 +50,15 @@ const DrawerWidget = (0, mobx_react_1.observer)(function ({ session, }) {
50
50
  const [toolbarHeight, setToolbarHeight] = (0, react_1.useState)(0);
51
51
  const [popoutDrawer, setPopoutDrawer] = (0, react_1.useState)(false);
52
52
  return (react_1.default.createElement(Drawer_1.default, { session: session },
53
- react_1.default.createElement(DrawerHeader_1.default, { onPopoutDrawer: () => setPopoutDrawer(true), session: session, setToolbarHeight: setToolbarHeight }),
53
+ react_1.default.createElement(DrawerHeader_1.default, { onPopoutDrawer: () => {
54
+ setPopoutDrawer(true);
55
+ }, session: session, setToolbarHeight: setToolbarHeight }),
54
56
  react_1.default.createElement(react_1.Suspense, { fallback: react_1.default.createElement(ui_1.LoadingEllipses, null) },
55
57
  react_1.default.createElement(react_error_boundary_1.ErrorBoundary, { FallbackComponent: ({ error }) => react_1.default.createElement(ui_1.ErrorMessage, { error: error }) }, DrawerComponent ? (popoutDrawer ? (react_1.default.createElement(react_1.default.Fragment, null,
56
58
  react_1.default.createElement("div", null, "Opened in dialog..."),
57
- react_1.default.createElement(ModalWidget, { session: session, onClose: () => setPopoutDrawer(false) }))) : (react_1.default.createElement(react_1.default.Fragment, null,
59
+ react_1.default.createElement(ModalWidget, { session: session, onClose: () => {
60
+ setPopoutDrawer(false);
61
+ } }))) : (react_1.default.createElement(react_1.default.Fragment, null,
58
62
  react_1.default.createElement(DrawerComponent, { model: visibleWidget, session: session, toolbarHeight: toolbarHeight }),
59
63
  react_1.default.createElement("div", { style: { height: 300 } })))) : null))));
60
64
  });
@@ -48,7 +48,9 @@ const DrawerWidgetSelector = (0, mobx_react_1.observer)(function ({ session, })
48
48
  const { HeadingComponent, heading } = widgetType;
49
49
  return (react_1.default.createElement(material_1.MenuItem, { "data-testid": `widget-drawer-selects-item-${widget.type}`, key: widget.id, value: widget.id },
50
50
  HeadingComponent ? (react_1.default.createElement(HeadingComponent, { model: widget })) : (react_1.default.createElement(material_1.Typography, { variant: "h6", color: "inherit" }, heading)),
51
- react_1.default.createElement(material_1.IconButton, { "data-testid": `${widget.type}-drawer-delete`, color: "inherit", "aria-label": "Delete", onClick: () => session.hideWidget(widget) },
51
+ react_1.default.createElement(material_1.IconButton, { "data-testid": `${widget.type}-drawer-delete`, color: "inherit", "aria-label": "Delete", onClick: () => {
52
+ session.hideWidget(widget);
53
+ } },
52
54
  react_1.default.createElement(Delete_1.default, null))));
53
55
  }))));
54
56
  });
@@ -67,12 +67,10 @@ const ModalWidget = (0, mobx_react_1.observer)(function ({ session, onClose, })
67
67
  return null;
68
68
  }
69
69
  const { ReactComponent } = pluginManager.getWidgetType(visibleWidget.type);
70
- const Component = visibleWidget
71
- ? pluginManager.evaluateExtensionPoint('Core-replaceWidget', ReactComponent, {
72
- session,
73
- model: visibleWidget,
74
- })
75
- : null;
70
+ const Component = pluginManager.evaluateExtensionPoint('Core-replaceWidget', ReactComponent, {
71
+ session,
72
+ model: visibleWidget,
73
+ });
76
74
  return (react_1.default.createElement(ui_1.Dialog, { open: true, onClose: onClose, maxWidth: "xl", header: react_1.default.createElement(DrawerAppBar, { onClose: onClose, session: session }) }, Component ? (react_1.default.createElement(react_1.Suspense, { fallback: react_1.default.createElement("div", null, "Loading...") },
77
75
  react_1.default.createElement(material_1.Paper, { className: classes.paper },
78
76
  react_1.default.createElement(Component, { model: visibleWidget, session: session, modal: true, overrideDimensions: {
@@ -54,7 +54,7 @@ const ViewContainer = (0, mobx_react_1.observer)(function ({ view, onClose, onMi
54
54
  (0, react_1.useEffect)(() => {
55
55
  function handleSelectView(e) {
56
56
  var _a;
57
- if (e.target instanceof Element && ((_a = ref === null || ref === void 0 ? void 0 : ref.current) === null || _a === void 0 ? void 0 : _a.contains(e.target))) {
57
+ if (e.target instanceof Element && ((_a = ref.current) === null || _a === void 0 ? void 0 : _a.contains(e.target))) {
58
58
  session.setFocusedViewId(view.id);
59
59
  }
60
60
  }
@@ -33,7 +33,9 @@ const ViewContainerTitle = (0, mobx_react_1.observer)(function ({ view, }) {
33
33
  return (react_1.default.createElement(material_1.Tooltip, { title: "Rename view", arrow: true },
34
34
  react_1.default.createElement(EditableTypography_1.default, { value: view.displayName ||
35
35
  // @ts-expect-error
36
- `${((_a = view.assemblyNames) === null || _a === void 0 ? void 0 : _a.join(',')) || 'Untitled view'}${view.minimized ? ' (minimized)' : ''}`, setValue: val => view.setDisplayName(val), variant: "body2", classes: {
36
+ `${((_a = view.assemblyNames) === null || _a === void 0 ? void 0 : _a.join(',')) || 'Untitled view'}${view.minimized ? ' (minimized)' : ''}`, setValue: val => {
37
+ view.setDisplayName(val);
38
+ }, variant: "body2", classes: {
37
39
  input: classes.input,
38
40
  inputBase: classes.inputBase,
39
41
  inputRoot: classes.inputRoot,
@@ -68,8 +68,10 @@ const ViewHeader = (0, mobx_react_1.observer)(function ({ view, onClose, onMinim
68
68
  // scroll the view into view when first mounted. note: this effect will run
69
69
  // only once, because of the empty array second param
70
70
  (0, react_1.useEffect)(() => {
71
- var _a, _b;
72
- (_b = (_a = scrollRef.current) === null || _a === void 0 ? void 0 : _a.scrollIntoView) === null || _b === void 0 ? void 0 : _b.call(_a, { block: 'center' });
71
+ var _a;
72
+ if (typeof jest === 'undefined') {
73
+ (_a = scrollRef.current) === null || _a === void 0 ? void 0 : _a.scrollIntoView({ block: 'center' });
74
+ }
73
75
  }, []);
74
76
  return (react_1.default.createElement("div", { ref: scrollRef, className: classes.viewHeader },
75
77
  react_1.default.createElement(ViewMenu_1.default, { model: view, IconProps: { className: classes.icon } }),
@@ -33,18 +33,23 @@ const useStyles = (0, mui_1.makeStyles)()(theme => ({
33
33
  selectPaper: {
34
34
  padding: theme.spacing(4),
35
35
  },
36
+ m2: {
37
+ margin: 2,
38
+ },
36
39
  }));
37
40
  const ViewLauncher = (0, mobx_react_1.observer)(({ session }) => {
38
41
  var _a;
39
42
  const { classes } = useStyles();
40
43
  const { pluginManager } = (0, util_1.getEnv)(session);
41
44
  const viewTypes = pluginManager.getElementTypeRecord('view').all();
42
- const [value, setValue] = (0, react_1.useState)((_a = viewTypes[0]) === null || _a === void 0 ? void 0 : _a.name);
45
+ const [value, setValue] = (0, react_1.useState)(((_a = viewTypes[0]) === null || _a === void 0 ? void 0 : _a.name) || '');
43
46
  return (react_1.default.createElement(material_1.Paper, { className: classes.selectPaper },
44
47
  react_1.default.createElement(material_1.Typography, null, "Select a view to launch"),
45
- react_1.default.createElement(material_1.FormControl, { style: { margin: 2 } },
46
- react_1.default.createElement(material_1.Select, { value: value, onChange: event => setValue(event.target.value) }, viewTypes.map(({ displayName, name }) => (react_1.default.createElement(material_1.MenuItem, { key: name, value: name }, displayName))))),
47
- react_1.default.createElement(material_1.FormControl, { style: { margin: 2 } },
48
+ react_1.default.createElement(material_1.FormControl, { className: classes.m2 },
49
+ react_1.default.createElement(material_1.Select, { value: value, onChange: event => {
50
+ setValue(event.target.value);
51
+ } }, viewTypes.map(({ displayName, name }) => (react_1.default.createElement(material_1.MenuItem, { key: name, value: name }, displayName))))),
52
+ react_1.default.createElement(material_1.FormControl, { className: classes.m2 },
48
53
  react_1.default.createElement(material_1.Button, { onClick: () => session.addView(value, {}), variant: "contained", color: "primary" }, "Launch view"))));
49
54
  });
50
55
  exports.default = ViewLauncher;
@@ -16,7 +16,6 @@ const KeyboardDoubleArrowUp_1 = __importDefault(require("@mui/icons-material/Key
16
16
  const KeyboardArrowDown_1 = __importDefault(require("@mui/icons-material/KeyboardArrowDown"));
17
17
  const KeyboardArrowUp_1 = __importDefault(require("@mui/icons-material/KeyboardArrowUp"));
18
18
  const ViewMenu = (0, mobx_react_1.observer)(function ({ model, IconButtonProps, IconProps, }) {
19
- const { menuItems } = model;
20
19
  const session = (0, util_1.getSession)(model);
21
20
  const popupState = (0, hooks_1.usePopupState)({
22
21
  popupId: 'viewMenu',
@@ -26,12 +25,14 @@ const ViewMenu = (0, mobx_react_1.observer)(function ({ model, IconButtonProps,
26
25
  // a confusing bug related to it! see
27
26
  // https://github.com/GMOD/jbrowse-components/issues/4115
28
27
  //
29
- // Make sure to test the Breakpoint split view menu checkboxes if you
30
- // intend to change this
28
+ // Make sure to test the Breakpoint split view menu checkboxes if you intend
29
+ // to change this
31
30
  return (react_1.default.createElement(react_1.default.Fragment, null,
32
31
  react_1.default.createElement(material_1.IconButton, { ...IconButtonProps, ...(0, hooks_1.bindTrigger)(popupState), "data-testid": "view_menu_icon" },
33
32
  react_1.default.createElement(Menu_1.default, { ...IconProps, fontSize: "small" })),
34
- react_1.default.createElement(CascadingMenu_1.default, { ...(0, hooks_1.bindPopover)(popupState), onMenuItemClick: (_event, callback) => callback(), menuItems: [
33
+ react_1.default.createElement(CascadingMenu_1.default, { ...(0, hooks_1.bindPopover)(popupState), onMenuItemClick: (_event, callback) => {
34
+ callback();
35
+ }, menuItems: [
35
36
  ...(session.views.length > 1
36
37
  ? [
37
38
  {
@@ -41,30 +42,36 @@ const ViewMenu = (0, mobx_react_1.observer)(function ({ model, IconButtonProps,
41
42
  {
42
43
  label: 'Move view to top',
43
44
  icon: KeyboardDoubleArrowUp_1.default,
44
- onClick: () => session.moveViewToTop(model.id),
45
+ onClick: () => {
46
+ session.moveViewToTop(model.id);
47
+ },
45
48
  },
46
49
  {
47
50
  label: 'Move view up',
48
51
  icon: KeyboardArrowUp_1.default,
49
- onClick: () => session.moveViewUp(model.id),
52
+ onClick: () => {
53
+ session.moveViewUp(model.id);
54
+ },
50
55
  },
51
56
  {
52
57
  label: 'Move view down',
53
58
  icon: KeyboardArrowDown_1.default,
54
- onClick: () => session.moveViewDown(model.id),
59
+ onClick: () => {
60
+ session.moveViewDown(model.id);
61
+ },
55
62
  },
56
63
  {
57
64
  label: 'Move view to bottom',
58
65
  icon: KeyboardDoubleArrowDown_1.default,
59
- onClick: () => session.moveViewToBottom(model.id),
66
+ onClick: () => {
67
+ session.moveViewToBottom(model.id);
68
+ },
60
69
  },
61
70
  ],
62
71
  },
63
72
  ]
64
73
  : []),
65
- // <=1.3.3 didn't use a function, so check as value also
66
- ...((typeof menuItems === 'function' ? menuItems() : menuItems) ||
67
- []),
74
+ ...model.menuItems(),
68
75
  ], popupState: popupState })));
69
76
  });
70
77
  exports.default = ViewMenu;
@@ -43,7 +43,11 @@ const ViewPanel = (0, mobx_react_1.observer)(function ({ view, session, }) {
43
43
  throw new Error(`unknown view type ${view.type}`);
44
44
  }
45
45
  const { ReactComponent } = viewType;
46
- return (react_1.default.createElement(ViewContainer_1.default, { view: view, onClose: () => session.removeView(view), onMinimize: () => view.setMinimized(!view.minimized) }, !view.minimized ? (react_1.default.createElement(react_error_boundary_1.ErrorBoundary, { FallbackComponent: ({ error }) => react_1.default.createElement(ErrorMessage_1.default, { error: error }) },
46
+ return (react_1.default.createElement(ViewContainer_1.default, { view: view, onClose: () => {
47
+ session.removeView(view);
48
+ }, onMinimize: () => {
49
+ view.setMinimized(!view.minimized);
50
+ } }, !view.minimized ? (react_1.default.createElement(react_error_boundary_1.ErrorBoundary, { FallbackComponent: ({ error }) => react_1.default.createElement(ErrorMessage_1.default, { error: error }) },
47
51
  react_1.default.createElement(react_1.Suspense, { fallback: react_1.default.createElement(LoadingEllipses_1.default, { variant: "h6" }) },
48
52
  react_1.default.createElement(ReactComponent, { model: view, session: session })))) : (false)));
49
53
  });
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+ import { SessionWithFocusedViewAndDrawerWidgets } from '@jbrowse/core/util';
3
+ import { SnackbarMessage } from '@jbrowse/core/ui/SnackbarModel';
4
+ import { MenuItem as JBMenuItem } from '@jbrowse/core/ui/Menu';
5
+ interface Props {
6
+ HeaderButtons?: React.ReactElement;
7
+ session: SessionWithFocusedViewAndDrawerWidgets & {
8
+ savedSessionNames: string[];
9
+ menus: {
10
+ label: string;
11
+ menuItems: JBMenuItem[];
12
+ }[];
13
+ renameCurrentSession: (arg: string) => void;
14
+ snackbarMessages: SnackbarMessage[];
15
+ popSnackbarMessage: () => unknown;
16
+ };
17
+ }
18
+ declare const ViewsContainer: (props: Props) => React.JSX.Element;
19
+ export default ViewsContainer;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const react_1 = __importDefault(require("react"));
7
+ const mui_1 = require("tss-react/mui");
8
+ const mobx_react_1 = require("mobx-react");
9
+ // locals
10
+ const ViewLauncher_1 = __importDefault(require("./ViewLauncher"));
11
+ const ViewPanel_1 = __importDefault(require("./ViewPanel"));
12
+ const useStyles = (0, mui_1.makeStyles)()({
13
+ viewsContainer: {
14
+ overflowY: 'auto',
15
+ gridRow: 'components',
16
+ },
17
+ });
18
+ const ViewsContainer = (0, mobx_react_1.observer)(function ViewsContainer(props) {
19
+ const { session } = props;
20
+ const { views } = session;
21
+ const { classes } = useStyles();
22
+ return (react_1.default.createElement("div", { className: classes.viewsContainer },
23
+ views.length > 0 ? (views.map(view => (react_1.default.createElement(ViewPanel_1.default, { key: `view-${view.id}`, view: view, session: session })))) : (react_1.default.createElement(ViewLauncher_1.default, { ...props })),
24
+ react_1.default.createElement("div", { style: { height: 300 } })));
25
+ });
26
+ exports.default = ViewsContainer;
@@ -37,7 +37,7 @@ export declare function SessionAssembliesMixin(pluginManager: PluginManager, ass
37
37
  /**
38
38
  * #action
39
39
  */
40
- addSessionAssembly(conf: AnyConfiguration): {
40
+ addSessionAssembly(conf: AnyConfiguration): ({
41
41
  [x: string]: any;
42
42
  } & import("mobx-state-tree/dist/internal").NonEmptyObject & {
43
43
  setSubschema(slotName: string, data: Record<string, unknown>): Record<string, unknown> | ({
@@ -70,7 +70,7 @@ export declare function SessionAssembliesMixin(pluginManager: PluginManager, ass
70
70
  defaultValue: string;
71
71
  description: string;
72
72
  };
73
- }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "name">>>;
73
+ }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "name">>>) | undefined;
74
74
  /**
75
75
  * #action
76
76
  */
@@ -121,7 +121,7 @@ export function JBrowseConfigF({ pluginManager, assemblyConfigSchema, }) {
121
121
  * #slot
122
122
  */
123
123
  defaultSession: types.optional(types.frozen(), {
124
- name: `New Session`,
124
+ name: 'New Session',
125
125
  }),
126
126
  });
127
127
  }
@@ -137,7 +137,7 @@ export declare function JBrowseModelF({ pluginManager, assemblyConfigSchema, }:
137
137
  /**
138
138
  * #action
139
139
  */
140
- addAssemblyConf(conf: AnyConfigurationModel): {
140
+ addAssemblyConf(conf: AnyConfigurationModel): ({
141
141
  [x: string]: any;
142
142
  } & import("mobx-state-tree/dist/internal").NonEmptyObject & {
143
143
  setSubschema(slotName: string, data: Record<string, unknown>): Record<string, unknown> | ({
@@ -147,7 +147,7 @@ export declare function JBrowseModelF({ pluginManager, assemblyConfigSchema, }:
147
147
  [x: string]: any;
148
148
  } & import("mobx-state-tree/dist/internal").NonEmptyObject & any & import("mobx-state-tree").IStateTreeNode<import("@jbrowse/core/configuration").AnyConfigurationSchemaType>);
149
149
  } & import("mobx-state-tree").IStateTreeNode<import("@jbrowse/core/configuration").AnyConfigurationSchemaType>);
150
- } & import("mobx-state-tree").IStateTreeNode<import("@jbrowse/core/configuration").AnyConfigurationSchemaType>;
150
+ } & import("mobx-state-tree").IStateTreeNode<import("@jbrowse/core/configuration").AnyConfigurationSchemaType>) | undefined;
151
151
  /**
152
152
  * #action
153
153
  */
@@ -27,7 +27,6 @@ export function JBrowseModelF({ pluginManager, assemblyConfigSchema, }) {
27
27
  * #getter
28
28
  */
29
29
  get rpcManager() {
30
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
31
30
  return getParent(self).rpcManager;
32
31
  },
33
32
  }))
@@ -103,7 +102,6 @@ export function JBrowseModelF({ pluginManager, assemblyConfigSchema, }) {
103
102
  */
104
103
  addPlugin(pluginDefinition) {
105
104
  self.plugins.push(pluginDefinition);
106
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
107
105
  const rootModel = getParent(self);
108
106
  rootModel.setPluginsUpdated(true);
109
107
  },
@@ -111,20 +109,22 @@ export function JBrowseModelF({ pluginManager, assemblyConfigSchema, }) {
111
109
  * #action
112
110
  */
113
111
  removePlugin(pluginDefinition) {
114
- self.plugins = cast(self.plugins.filter(plugin => plugin.url !== pluginDefinition.url ||
112
+ self.plugins = cast(self.plugins.filter(plugin =>
113
+ // @ts-expect-error
114
+ plugin.url !== pluginDefinition.url ||
115
+ // @ts-expect-error
115
116
  plugin.umdUrl !== pluginDefinition.umdUrl ||
117
+ // @ts-expect-error
116
118
  plugin.cjsUrl !== pluginDefinition.cjsUrl ||
119
+ // @ts-expect-error
117
120
  plugin.esmUrl !== pluginDefinition.esmUrl));
118
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
119
121
  getParent(self).setPluginsUpdated(true);
120
122
  },
121
123
  /**
122
124
  * #action
123
125
  */
124
126
  setDefaultSessionConf(sessionConf) {
125
- const newDefault =
126
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
127
- getParent(self).session.name === sessionConf.name
127
+ const newDefault = getParent(self).session.name === sessionConf.name
128
128
  ? getSnapshot(sessionConf)
129
129
  : toJS(sessionConf);
130
130
  if (!newDefault.name) {
package/esm/ui/App/App.js CHANGED
@@ -5,10 +5,9 @@ import { observer } from 'mobx-react';
5
5
  import Snackbar from '@jbrowse/core/ui/Snackbar';
6
6
  // locals
7
7
  import AppToolbar from './AppToolbar';
8
- import ViewLauncher from './ViewLauncher';
9
- import ViewPanel from './ViewPanel';
10
8
  import DialogQueue from './DialogQueue';
11
9
  import AppFab from './AppFab';
10
+ import ViewsContainer from './ViewsContainer';
12
11
  const DrawerWidget = lazy(() => import('./DrawerWidget'));
13
12
  const useStyles = makeStyles()(theme => ({
14
13
  root: {
@@ -23,10 +22,6 @@ const useStyles = makeStyles()(theme => ({
23
22
  gridTemplateRows: '[menubar] min-content [components] auto',
24
23
  height: '100vh',
25
24
  },
26
- viewContainer: {
27
- overflowY: 'auto',
28
- gridRow: 'components',
29
- },
30
25
  appBar: {
31
26
  flexGrow: 1,
32
27
  gridRow: 'menubar',
@@ -37,14 +32,6 @@ const LazyDrawerWidget = observer(function (props) {
37
32
  return (React.createElement(Suspense, { fallback: null },
38
33
  React.createElement(DrawerWidget, { session: session })));
39
34
  });
40
- const ViewContainer = observer(function (props) {
41
- const { session } = props;
42
- const { views } = session;
43
- const { classes } = useStyles();
44
- return (React.createElement("div", { className: classes.viewContainer },
45
- views.length > 0 ? (views.map(view => (React.createElement(ViewPanel, { key: `view-${view.id}`, view: view, session: session })))) : (React.createElement(ViewLauncher, { ...props })),
46
- React.createElement("div", { style: { height: 300 } })));
47
- });
48
35
  const App = observer(function (props) {
49
36
  const { session } = props;
50
37
  const { classes } = useStyles();
@@ -52,13 +39,13 @@ const App = observer(function (props) {
52
39
  const drawerVisible = visibleWidget && !minimized;
53
40
  const d = drawerVisible ? `[drawer] ${drawerWidth}px` : undefined;
54
41
  const grid = drawerPosition === 'right' ? ['[main] 1fr', d] : [d, '[main] 1fr'];
55
- return (React.createElement("div", { className: classes.root, style: { gridTemplateColumns: grid === null || grid === void 0 ? void 0 : grid.filter(f => !!f).join(' ') } },
42
+ return (React.createElement("div", { className: classes.root, style: { gridTemplateColumns: grid.filter(f => !!f).join(' ') } },
56
43
  drawerVisible && drawerPosition === 'left' ? (React.createElement(LazyDrawerWidget, { session: session })) : null,
57
44
  React.createElement(DialogQueue, { session: session }),
58
45
  React.createElement("div", { className: classes.appContainer },
59
46
  React.createElement(AppBar, { className: classes.appBar, position: "static" },
60
47
  React.createElement(AppToolbar, { ...props })),
61
- React.createElement(ViewContainer, { ...props })),
48
+ React.createElement(ViewsContainer, { ...props })),
62
49
  React.createElement(AppFab, { session: session }),
63
50
  drawerVisible && drawerPosition === 'right' ? (React.createElement(LazyDrawerWidget, { session: session })) : null,
64
51
  React.createElement(Snackbar, { session: session })));
@@ -22,7 +22,9 @@ const AppFab = observer(function ({ session, }) {
22
22
  const { minimized, activeWidgets, drawerPosition } = session;
23
23
  const { classes } = useStyles();
24
24
  return activeWidgets.size > 0 && minimized ? (React.createElement(Tooltip, { title: "Open drawer widget" },
25
- React.createElement(Fab, { className: drawerPosition === 'right' ? classes.right : classes.left, color: "primary", "data-testid": "drawer-maximize", onClick: () => session.showWidgetDrawer() },
25
+ React.createElement(Fab, { className: drawerPosition === 'right' ? classes.right : classes.left, color: "primary", "data-testid": "drawer-maximize", onClick: () => {
26
+ session.showWidgetDrawer();
27
+ } },
26
28
  React.createElement(LaunchIcon, null)))) : null;
27
29
  });
28
30
  export default AppFab;
@@ -3,13 +3,13 @@ import { SessionWithDrawerWidgets } from '@jbrowse/core/util';
3
3
  import { MenuItem as JBMenuItem } from '@jbrowse/core/ui/Menu';
4
4
  import { SnackbarMessage } from '@jbrowse/core/ui/SnackbarModel';
5
5
  type AppSession = SessionWithDrawerWidgets & {
6
- savedSessionNames: string[];
7
6
  menus: {
8
7
  label: string;
9
8
  menuItems: JBMenuItem[];
10
9
  }[];
11
- renameCurrentSession: (arg: string) => void;
10
+ savedSessionNames?: string[];
12
11
  snackbarMessages: SnackbarMessage[];
12
+ renameCurrentSession: (arg: string) => void;
13
13
  popSnackbarMessage: () => unknown;
14
14
  };
15
15
  declare const AppToolbar: ({ session, HeaderButtons, }: {
@@ -26,7 +26,7 @@ const Drawer = observer(function ({ children, session, }) {
26
26
  useEffect(() => {
27
27
  function handleSelectView(e) {
28
28
  var _a, _b, _c;
29
- if (e.target instanceof Element && ((_a = ref === null || ref === void 0 ? void 0 : ref.current) === null || _a === void 0 ? void 0 : _a.contains(e.target))) {
29
+ if (e.target instanceof Element && ((_a = ref.current) === null || _a === void 0 ? void 0 : _a.contains(e.target))) {
30
30
  // @ts-ignore
31
31
  const visibleWidgetId = (_c = (_b = session.visibleWidget) === null || _b === void 0 ? void 0 : _b.view) === null || _c === void 0 ? void 0 : _c.id;
32
32
  if (visibleWidgetId) {
@@ -40,7 +40,7 @@ const Drawer = observer(function ({ children, session, }) {
40
40
  document.removeEventListener('mousedown', handleSelectView);
41
41
  document.removeEventListener('keydown', handleSelectView);
42
42
  };
43
- }, [ref, session]);
43
+ }, [session]);
44
44
  return (React.createElement(Paper, { ref: ref, className: classes.paper, elevation: 16, square: true },
45
45
  drawerPosition === 'right' ? (React.createElement(ResizeHandle, { onDrag: session.resizeDrawer, className: classes.resizeHandle, vertical: true })) : null,
46
46
  children,
@@ -9,7 +9,9 @@ const DrawerControls = observer(function ({ session, }) {
9
9
  const [anchorEl, setAnchorEl] = useState(null);
10
10
  const { drawerPosition, visibleWidget } = session;
11
11
  return (React.createElement(React.Fragment, null,
12
- React.createElement(IconButton, { color: "inherit", onClick: event => setAnchorEl(event.currentTarget) },
12
+ React.createElement(IconButton, { color: "inherit", onClick: event => {
13
+ setAnchorEl(event.currentTarget);
14
+ } },
13
15
  React.createElement(MoreVertIcon, null)),
14
16
  React.createElement(Tooltip, { title: "Minimize drawer" },
15
17
  React.createElement(IconButton, { "data-testid": "drawer-minimize", color: "inherit", onClick: () => {
@@ -18,9 +20,13 @@ const DrawerControls = observer(function ({ session, }) {
18
20
  } },
19
21
  React.createElement(MinimizeIcon, null))),
20
22
  React.createElement(Tooltip, { title: "Close drawer" },
21
- React.createElement(IconButton, { color: "inherit", onClick: () => session.hideWidget(visibleWidget) },
23
+ React.createElement(IconButton, { color: "inherit", onClick: () => {
24
+ session.hideWidget(visibleWidget);
25
+ } },
22
26
  React.createElement(CloseIcon, null))),
23
- React.createElement(Menu, { anchorEl: anchorEl, open: Boolean(anchorEl), onClose: () => setAnchorEl(null) }, ['left', 'right'].map(option => (React.createElement(MenuItem, { key: option, selected: drawerPosition === 'option', onClick: () => {
27
+ React.createElement(Menu, { anchorEl: anchorEl, open: Boolean(anchorEl), onClose: () => {
28
+ setAnchorEl(null);
29
+ } }, ['left', 'right'].map(option => (React.createElement(MenuItem, { key: option, selected: drawerPosition === 'option', onClick: () => {
24
30
  session.setDrawerPosition(option);
25
31
  setAnchorEl(null);
26
32
  } }, option))))));
@@ -26,11 +26,15 @@ const DrawerHeader = observer(function ({ session, setToolbarHeight, onPopoutDra
26
26
  const viewWidgetId = (_b = (_a = session.visibleWidget) === null || _a === void 0 ? void 0 : _a.view) === null || _b === void 0 ? void 0 : _b.id;
27
27
  return (React.createElement(AppBar, { position: "sticky", className: focusedViewId === viewWidgetId
28
28
  ? classes.headerFocused
29
- : classes.headerUnfocused, ref: ref => setToolbarHeight((ref === null || ref === void 0 ? void 0 : ref.getBoundingClientRect().height) || 0) },
29
+ : classes.headerUnfocused, ref: ref => {
30
+ setToolbarHeight((ref === null || ref === void 0 ? void 0 : ref.getBoundingClientRect().height) || 0);
31
+ } },
30
32
  React.createElement(Toolbar, { disableGutters: true },
31
33
  React.createElement(DrawerWidgetSelector, { session: session }),
32
34
  React.createElement(Tooltip, { title: "Open drawer in dialog" },
33
- React.createElement(IconButton, { color: "inherit", onClick: () => onPopoutDrawer() },
35
+ React.createElement(IconButton, { color: "inherit", onClick: () => {
36
+ onPopoutDrawer();
37
+ } },
34
38
  React.createElement(LaunchIcon, null))),
35
39
  React.createElement("div", { className: classes.spacer }),
36
40
  React.createElement(DrawerControls, { session: session }))));
@@ -22,11 +22,15 @@ const DrawerWidget = observer(function ({ session, }) {
22
22
  const [toolbarHeight, setToolbarHeight] = useState(0);
23
23
  const [popoutDrawer, setPopoutDrawer] = useState(false);
24
24
  return (React.createElement(Drawer, { session: session },
25
- React.createElement(DrawerHeader, { onPopoutDrawer: () => setPopoutDrawer(true), session: session, setToolbarHeight: setToolbarHeight }),
25
+ React.createElement(DrawerHeader, { onPopoutDrawer: () => {
26
+ setPopoutDrawer(true);
27
+ }, session: session, setToolbarHeight: setToolbarHeight }),
26
28
  React.createElement(Suspense, { fallback: React.createElement(LoadingEllipses, null) },
27
29
  React.createElement(ErrorBoundary, { FallbackComponent: ({ error }) => React.createElement(ErrorMessage, { error: error }) }, DrawerComponent ? (popoutDrawer ? (React.createElement(React.Fragment, null,
28
30
  React.createElement("div", null, "Opened in dialog..."),
29
- React.createElement(ModalWidget, { session: session, onClose: () => setPopoutDrawer(false) }))) : (React.createElement(React.Fragment, null,
31
+ React.createElement(ModalWidget, { session: session, onClose: () => {
32
+ setPopoutDrawer(false);
33
+ } }))) : (React.createElement(React.Fragment, null,
30
34
  React.createElement(DrawerComponent, { model: visibleWidget, session: session, toolbarHeight: toolbarHeight }),
31
35
  React.createElement("div", { style: { height: 300 } })))) : null))));
32
36
  });
@@ -43,7 +43,9 @@ const DrawerWidgetSelector = observer(function ({ session, }) {
43
43
  const { HeadingComponent, heading } = widgetType;
44
44
  return (React.createElement(MenuItem, { "data-testid": `widget-drawer-selects-item-${widget.type}`, key: widget.id, value: widget.id },
45
45
  HeadingComponent ? (React.createElement(HeadingComponent, { model: widget })) : (React.createElement(Typography, { variant: "h6", color: "inherit" }, heading)),
46
- React.createElement(IconButton, { "data-testid": `${widget.type}-drawer-delete`, color: "inherit", "aria-label": "Delete", onClick: () => session.hideWidget(widget) },
46
+ React.createElement(IconButton, { "data-testid": `${widget.type}-drawer-delete`, color: "inherit", "aria-label": "Delete", onClick: () => {
47
+ session.hideWidget(widget);
48
+ } },
47
49
  React.createElement(DeleteIcon, null))));
48
50
  }))));
49
51
  });
@@ -39,12 +39,10 @@ const ModalWidget = observer(function ({ session, onClose, }) {
39
39
  return null;
40
40
  }
41
41
  const { ReactComponent } = pluginManager.getWidgetType(visibleWidget.type);
42
- const Component = visibleWidget
43
- ? pluginManager.evaluateExtensionPoint('Core-replaceWidget', ReactComponent, {
44
- session,
45
- model: visibleWidget,
46
- })
47
- : null;
42
+ const Component = pluginManager.evaluateExtensionPoint('Core-replaceWidget', ReactComponent, {
43
+ session,
44
+ model: visibleWidget,
45
+ });
48
46
  return (React.createElement(Dialog, { open: true, onClose: onClose, maxWidth: "xl", header: React.createElement(DrawerAppBar, { onClose: onClose, session: session }) }, Component ? (React.createElement(Suspense, { fallback: React.createElement("div", null, "Loading...") },
49
47
  React.createElement(Paper, { className: classes.paper },
50
48
  React.createElement(Component, { model: visibleWidget, session: session, modal: true, overrideDimensions: {
@@ -26,7 +26,7 @@ const ViewContainer = observer(function ({ view, onClose, onMinimize, children,
26
26
  useEffect(() => {
27
27
  function handleSelectView(e) {
28
28
  var _a;
29
- if (e.target instanceof Element && ((_a = ref === null || ref === void 0 ? void 0 : ref.current) === null || _a === void 0 ? void 0 : _a.contains(e.target))) {
29
+ if (e.target instanceof Element && ((_a = ref.current) === null || _a === void 0 ? void 0 : _a.contains(e.target))) {
30
30
  session.setFocusedViewId(view.id);
31
31
  }
32
32
  }
@@ -28,7 +28,9 @@ const ViewContainerTitle = observer(function ({ view, }) {
28
28
  return (React.createElement(Tooltip, { title: "Rename view", arrow: true },
29
29
  React.createElement(EditableTypography, { value: view.displayName ||
30
30
  // @ts-expect-error
31
- `${((_a = view.assemblyNames) === null || _a === void 0 ? void 0 : _a.join(',')) || 'Untitled view'}${view.minimized ? ' (minimized)' : ''}`, setValue: val => view.setDisplayName(val), variant: "body2", classes: {
31
+ `${((_a = view.assemblyNames) === null || _a === void 0 ? void 0 : _a.join(',')) || 'Untitled view'}${view.minimized ? ' (minimized)' : ''}`, setValue: val => {
32
+ view.setDisplayName(val);
33
+ }, variant: "body2", classes: {
32
34
  input: classes.input,
33
35
  inputBase: classes.inputBase,
34
36
  inputRoot: classes.inputRoot,
@@ -40,8 +40,10 @@ const ViewHeader = observer(function ({ view, onClose, onMinimize, }) {
40
40
  // scroll the view into view when first mounted. note: this effect will run
41
41
  // only once, because of the empty array second param
42
42
  useEffect(() => {
43
- var _a, _b;
44
- (_b = (_a = scrollRef.current) === null || _a === void 0 ? void 0 : _a.scrollIntoView) === null || _b === void 0 ? void 0 : _b.call(_a, { block: 'center' });
43
+ var _a;
44
+ if (typeof jest === 'undefined') {
45
+ (_a = scrollRef.current) === null || _a === void 0 ? void 0 : _a.scrollIntoView({ block: 'center' });
46
+ }
45
47
  }, []);
46
48
  return (React.createElement("div", { ref: scrollRef, className: classes.viewHeader },
47
49
  React.createElement(ViewMenu, { model: view, IconProps: { className: classes.icon } }),
@@ -8,18 +8,23 @@ const useStyles = makeStyles()(theme => ({
8
8
  selectPaper: {
9
9
  padding: theme.spacing(4),
10
10
  },
11
+ m2: {
12
+ margin: 2,
13
+ },
11
14
  }));
12
15
  const ViewLauncher = observer(({ session }) => {
13
16
  var _a;
14
17
  const { classes } = useStyles();
15
18
  const { pluginManager } = getEnv(session);
16
19
  const viewTypes = pluginManager.getElementTypeRecord('view').all();
17
- const [value, setValue] = useState((_a = viewTypes[0]) === null || _a === void 0 ? void 0 : _a.name);
20
+ const [value, setValue] = useState(((_a = viewTypes[0]) === null || _a === void 0 ? void 0 : _a.name) || '');
18
21
  return (React.createElement(Paper, { className: classes.selectPaper },
19
22
  React.createElement(Typography, null, "Select a view to launch"),
20
- React.createElement(FormControl, { style: { margin: 2 } },
21
- React.createElement(Select, { value: value, onChange: event => setValue(event.target.value) }, viewTypes.map(({ displayName, name }) => (React.createElement(MenuItem, { key: name, value: name }, displayName))))),
22
- React.createElement(FormControl, { style: { margin: 2 } },
23
+ React.createElement(FormControl, { className: classes.m2 },
24
+ React.createElement(Select, { value: value, onChange: event => {
25
+ setValue(event.target.value);
26
+ } }, viewTypes.map(({ displayName, name }) => (React.createElement(MenuItem, { key: name, value: name }, displayName))))),
27
+ React.createElement(FormControl, { className: classes.m2 },
23
28
  React.createElement(Button, { onClick: () => session.addView(value, {}), variant: "contained", color: "primary" }, "Launch view"))));
24
29
  });
25
30
  export default ViewLauncher;
@@ -11,7 +11,6 @@ import KeyboardDoubleArrowUpIcon from '@mui/icons-material/KeyboardDoubleArrowUp
11
11
  import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
12
12
  import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp';
13
13
  const ViewMenu = observer(function ({ model, IconButtonProps, IconProps, }) {
14
- const { menuItems } = model;
15
14
  const session = getSession(model);
16
15
  const popupState = usePopupState({
17
16
  popupId: 'viewMenu',
@@ -21,12 +20,14 @@ const ViewMenu = observer(function ({ model, IconButtonProps, IconProps, }) {
21
20
  // a confusing bug related to it! see
22
21
  // https://github.com/GMOD/jbrowse-components/issues/4115
23
22
  //
24
- // Make sure to test the Breakpoint split view menu checkboxes if you
25
- // intend to change this
23
+ // Make sure to test the Breakpoint split view menu checkboxes if you intend
24
+ // to change this
26
25
  return (React.createElement(React.Fragment, null,
27
26
  React.createElement(IconButton, { ...IconButtonProps, ...bindTrigger(popupState), "data-testid": "view_menu_icon" },
28
27
  React.createElement(MenuIcon, { ...IconProps, fontSize: "small" })),
29
- React.createElement(CascadingMenu, { ...bindPopover(popupState), onMenuItemClick: (_event, callback) => callback(), menuItems: [
28
+ React.createElement(CascadingMenu, { ...bindPopover(popupState), onMenuItemClick: (_event, callback) => {
29
+ callback();
30
+ }, menuItems: [
30
31
  ...(session.views.length > 1
31
32
  ? [
32
33
  {
@@ -36,30 +37,36 @@ const ViewMenu = observer(function ({ model, IconButtonProps, IconProps, }) {
36
37
  {
37
38
  label: 'Move view to top',
38
39
  icon: KeyboardDoubleArrowUpIcon,
39
- onClick: () => session.moveViewToTop(model.id),
40
+ onClick: () => {
41
+ session.moveViewToTop(model.id);
42
+ },
40
43
  },
41
44
  {
42
45
  label: 'Move view up',
43
46
  icon: KeyboardArrowUpIcon,
44
- onClick: () => session.moveViewUp(model.id),
47
+ onClick: () => {
48
+ session.moveViewUp(model.id);
49
+ },
45
50
  },
46
51
  {
47
52
  label: 'Move view down',
48
53
  icon: KeyboardArrowDownIcon,
49
- onClick: () => session.moveViewDown(model.id),
54
+ onClick: () => {
55
+ session.moveViewDown(model.id);
56
+ },
50
57
  },
51
58
  {
52
59
  label: 'Move view to bottom',
53
60
  icon: KeyboardDoubleArrowDownIcon,
54
- onClick: () => session.moveViewToBottom(model.id),
61
+ onClick: () => {
62
+ session.moveViewToBottom(model.id);
63
+ },
55
64
  },
56
65
  ],
57
66
  },
58
67
  ]
59
68
  : []),
60
- // <=1.3.3 didn't use a function, so check as value also
61
- ...((typeof menuItems === 'function' ? menuItems() : menuItems) ||
62
- []),
69
+ ...model.menuItems(),
63
70
  ], popupState: popupState })));
64
71
  });
65
72
  export default ViewMenu;
@@ -15,7 +15,11 @@ const ViewPanel = observer(function ({ view, session, }) {
15
15
  throw new Error(`unknown view type ${view.type}`);
16
16
  }
17
17
  const { ReactComponent } = viewType;
18
- return (React.createElement(ViewContainer, { view: view, onClose: () => session.removeView(view), onMinimize: () => view.setMinimized(!view.minimized) }, !view.minimized ? (React.createElement(ErrorBoundary, { FallbackComponent: ({ error }) => React.createElement(ErrorMessage, { error: error }) },
18
+ return (React.createElement(ViewContainer, { view: view, onClose: () => {
19
+ session.removeView(view);
20
+ }, onMinimize: () => {
21
+ view.setMinimized(!view.minimized);
22
+ } }, !view.minimized ? (React.createElement(ErrorBoundary, { FallbackComponent: ({ error }) => React.createElement(ErrorMessage, { error: error }) },
19
23
  React.createElement(Suspense, { fallback: React.createElement(LoadingEllipses, { variant: "h6" }) },
20
24
  React.createElement(ReactComponent, { model: view, session: session })))) : (false)));
21
25
  });
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+ import { SessionWithFocusedViewAndDrawerWidgets } from '@jbrowse/core/util';
3
+ import { SnackbarMessage } from '@jbrowse/core/ui/SnackbarModel';
4
+ import { MenuItem as JBMenuItem } from '@jbrowse/core/ui/Menu';
5
+ interface Props {
6
+ HeaderButtons?: React.ReactElement;
7
+ session: SessionWithFocusedViewAndDrawerWidgets & {
8
+ savedSessionNames: string[];
9
+ menus: {
10
+ label: string;
11
+ menuItems: JBMenuItem[];
12
+ }[];
13
+ renameCurrentSession: (arg: string) => void;
14
+ snackbarMessages: SnackbarMessage[];
15
+ popSnackbarMessage: () => unknown;
16
+ };
17
+ }
18
+ declare const ViewsContainer: (props: Props) => React.JSX.Element;
19
+ export default ViewsContainer;
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+ import { makeStyles } from 'tss-react/mui';
3
+ import { observer } from 'mobx-react';
4
+ // locals
5
+ import ViewLauncher from './ViewLauncher';
6
+ import ViewPanel from './ViewPanel';
7
+ const useStyles = makeStyles()({
8
+ viewsContainer: {
9
+ overflowY: 'auto',
10
+ gridRow: 'components',
11
+ },
12
+ });
13
+ const ViewsContainer = observer(function ViewsContainer(props) {
14
+ const { session } = props;
15
+ const { views } = session;
16
+ const { classes } = useStyles();
17
+ return (React.createElement("div", { className: classes.viewsContainer },
18
+ views.length > 0 ? (views.map(view => (React.createElement(ViewPanel, { key: `view-${view.id}`, view: view, session: session })))) : (React.createElement(ViewLauncher, { ...props })),
19
+ React.createElement("div", { style: { height: 300 } })));
20
+ });
21
+ export default ViewsContainer;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jbrowse/app-core",
3
- "version": "2.13.0",
3
+ "version": "2.14.0",
4
4
  "description": "JBrowse 2 code shared between the 'full featured' apps e.g. jbrowse-web and jbrowse-desktop",
5
5
  "keywords": [
6
6
  "jbrowse",
@@ -32,7 +32,7 @@
32
32
  "build:esm": "tsc --build tsconfig.build.esm.json",
33
33
  "build:commonjs": "tsc --build tsconfig.build.commonjs.json",
34
34
  "build": "npm run build:esm && npm run build:commonjs",
35
- "test": "cd ../..; jest packages/app-core",
35
+ "test": "cd ../..; jest --passWithNoTests packages/app-core",
36
36
  "clean": "rimraf dist esm *.tsbuildinfo",
37
37
  "prebuild": "yarn clean",
38
38
  "prepack": "yarn build && yarn useDist",
@@ -42,7 +42,7 @@
42
42
  },
43
43
  "dependencies": {
44
44
  "@babel/runtime": "^7.16.3",
45
- "@jbrowse/product-core": "^2.13.0",
45
+ "@jbrowse/product-core": "^2.14.0",
46
46
  "@mui/icons-material": "^5.0.0",
47
47
  "@mui/material": "^5.10.17",
48
48
  "copy-to-clipboard": "^3.3.1",
@@ -60,5 +60,5 @@
60
60
  "publishConfig": {
61
61
  "access": "public"
62
62
  },
63
- "gitHead": "efe02fb9616e20e929cceeed46eb96420c1b6923"
63
+ "gitHead": "9fb8231d932db40adf0a283081765431756c66ff"
64
64
  }