@jbrowse/core 2.1.4 → 2.1.6

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 (65) hide show
  1. package/BaseFeatureWidget/BaseFeatureDetail.d.ts +4 -3
  2. package/BaseFeatureWidget/BaseFeatureDetail.js +16 -17
  3. package/BaseFeatureWidget/SequenceBox.d.ts +29 -0
  4. package/BaseFeatureWidget/SequenceBox.js +61 -0
  5. package/BaseFeatureWidget/SequenceFeatureDetails.d.ts +2 -8
  6. package/BaseFeatureWidget/SequenceFeatureDetails.js +123 -135
  7. package/BaseFeatureWidget/SequenceFeatureSettingsDialog.d.ts +9 -0
  8. package/BaseFeatureWidget/SequenceFeatureSettingsDialog.js +71 -0
  9. package/BaseFeatureWidget/SequenceHelpDialog.d.ts +4 -0
  10. package/BaseFeatureWidget/SequenceHelpDialog.js +51 -0
  11. package/BaseFeatureWidget/SequencePanel.d.ts +10 -0
  12. package/BaseFeatureWidget/SequencePanel.js +72 -0
  13. package/BaseFeatureWidget/index.d.ts +7 -0
  14. package/BaseFeatureWidget/index.js +21 -5
  15. package/BaseFeatureWidget/test_data/DLGAP3.d.ts +80 -0
  16. package/BaseFeatureWidget/test_data/DLGAP3.js +585 -0
  17. package/BaseFeatureWidget/test_data/NCDN.d.ts +141 -0
  18. package/BaseFeatureWidget/test_data/NCDN.js +1118 -0
  19. package/BaseFeatureWidget/types.d.ts +2 -2
  20. package/BaseFeatureWidget/util.d.ts +13 -2
  21. package/BaseFeatureWidget/util.js +13 -1
  22. package/PluginLoader.d.ts +29 -13
  23. package/PluginLoader.js +47 -77
  24. package/PluginManager.d.ts +4 -3
  25. package/PluginManager.js +16 -8
  26. package/assemblyManager/assembly.d.ts +8 -15
  27. package/assemblyManager/assembly.js +14 -17
  28. package/assemblyManager/assemblyManager.d.ts +37 -86
  29. package/assemblyManager/assemblyManager.js +2 -1
  30. package/configuration/configurationSlot.js +2 -1
  31. package/data_adapters/CytobandAdapter.js +1 -1
  32. package/package.json +3 -3
  33. package/pluggableElementTypes/ViewType.d.ts +2 -0
  34. package/pluggableElementTypes/ViewType.js +1 -0
  35. package/pluggableElementTypes/models/BaseConnectionModelFactory.d.ts +7 -5
  36. package/pluggableElementTypes/models/BaseConnectionModelFactory.js +3 -2
  37. package/pluggableElementTypes/models/BaseDisplayModel.d.ts +1 -1
  38. package/pluggableElementTypes/models/BaseDisplayModel.js +3 -2
  39. package/pluggableElementTypes/models/BaseTrackModel.d.ts +1 -1
  40. package/pluggableElementTypes/models/BaseTrackModel.js +1 -1
  41. package/pluggableElementTypes/models/baseTrackConfig.js +16 -4
  42. package/rpc/RpcManager.d.ts +1 -1
  43. package/rpc/RpcManager.js +4 -1
  44. package/rpc/WebWorkerRpcDriver.d.ts +2 -0
  45. package/rpc/WebWorkerRpcDriver.js +21 -11
  46. package/rpc/configSchema.js +4 -1
  47. package/tsconfig.build.tsbuildinfo +1 -1
  48. package/ui/AboutDialog.d.ts +6 -0
  49. package/ui/AboutDialog.js +42 -20
  50. package/ui/App.d.ts +1 -1
  51. package/ui/App.js +49 -42
  52. package/ui/DrawerWidget.js +11 -6
  53. package/ui/FatalErrorDialog.d.ts +6 -22
  54. package/ui/FatalErrorDialog.js +10 -29
  55. package/ui/theme.d.ts +18 -171
  56. package/ui/theme.js +17 -20
  57. package/util/calculateStaticBlocks.js +3 -8
  58. package/util/index.d.ts +5 -1
  59. package/util/index.js +34 -11
  60. package/util/simpleFeature.d.ts +1 -2
  61. package/util/stats.js +7 -5
  62. package/util/tracks.d.ts +5 -2
  63. package/util/tracks.js +15 -5
  64. package/util/types/index.d.ts +1 -1
  65. package/util/types/index.js +3 -1
@@ -1,5 +1,11 @@
1
1
  /// <reference types="react" />
2
2
  import { AnyConfigurationModel } from '../configuration';
3
+ export declare function FileInfo({ config }: {
4
+ config: AnyConfigurationModel;
5
+ }): JSX.Element | null;
6
+ export declare function AboutContents({ config }: {
7
+ config: AnyConfigurationModel;
8
+ }): JSX.Element;
3
9
  export default function AboutDialog({ config, handleClose, }: {
4
10
  config: AnyConfigurationModel;
5
11
  handleClose: () => void;
package/ui/AboutDialog.js CHANGED
@@ -26,6 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.AboutContents = exports.FileInfo = void 0;
29
30
  const react_1 = __importStar(require("react"));
30
31
  const copy_to_clipboard_1 = __importDefault(require("copy-to-clipboard"));
31
32
  const material_1 = require("@mui/material");
@@ -33,6 +34,7 @@ const Close_1 = __importDefault(require("@mui/icons-material/Close"));
33
34
  const mui_1 = require("tss-react/mui");
34
35
  const configuration_1 = require("../configuration");
35
36
  const util_1 = require("../util");
37
+ const tracks_1 = require("../util/tracks");
36
38
  const BaseFeatureDetail_1 = require("../BaseFeatureWidget/BaseFeatureDetail");
37
39
  const useStyles = (0, mui_1.makeStyles)()(theme => ({
38
40
  closeButton: {
@@ -45,14 +47,11 @@ const useStyles = (0, mui_1.makeStyles)()(theme => ({
45
47
  minWidth: 800,
46
48
  },
47
49
  }));
48
- function AboutDialog({ config, handleClose, }) {
49
- const { classes } = useStyles();
50
- const [info, setInfo] = (0, react_1.useState)();
50
+ function FileInfo({ config }) {
51
51
  const [error, setError] = (0, react_1.useState)();
52
- const [copied, setCopied] = (0, react_1.useState)(false);
52
+ const [info, setInfo] = (0, react_1.useState)();
53
53
  const session = (0, util_1.getSession)(config);
54
54
  const { rpcManager } = session;
55
- const conf = (0, configuration_1.readConfObject)(config);
56
55
  (0, react_1.useEffect)(() => {
57
56
  const aborter = new AbortController();
58
57
  const { signal } = aborter;
@@ -80,13 +79,6 @@ function AboutDialog({ config, handleClose, }) {
80
79
  cancelled = true;
81
80
  };
82
81
  }, [config, rpcManager]);
83
- let trackName = (0, configuration_1.readConfObject)(config, 'name');
84
- if ((0, configuration_1.readConfObject)(config, 'type') === 'ReferenceSequenceTrack') {
85
- const asm = session.assemblies.find(a => a.sequence === config.configuration);
86
- trackName = asm
87
- ? `Reference Sequence (${(0, configuration_1.readConfObject)(asm, 'displayName') || (0, configuration_1.readConfObject)(asm, 'name')})`
88
- : 'Reference Sequence';
89
- }
90
82
  const details = typeof info === 'string'
91
83
  ? {
92
84
  header: `<pre>${info
@@ -94,19 +86,49 @@ function AboutDialog({ config, handleClose, }) {
94
86
  .replace(/>/g, '&gt;')}</pre>`,
95
87
  }
96
88
  : info || {};
89
+ return info !== null ? (react_1.default.createElement(BaseFeatureDetail_1.BaseCard, { title: "File info" }, error ? (react_1.default.createElement(material_1.Typography, { color: "error" }, `${error}`)) : info === undefined ? ('Loading file data...') : (react_1.default.createElement(BaseFeatureDetail_1.Attributes, { attributes: details })))) : null;
90
+ }
91
+ exports.FileInfo = FileInfo;
92
+ function AboutContents({ config }) {
93
+ const [copied, setCopied] = (0, react_1.useState)(false);
94
+ const conf = (0, configuration_1.readConfObject)(config);
95
+ const session = (0, util_1.getSession)(config);
96
+ const hideUris = (0, configuration_1.getConf)(session, ['formatAbout', 'hideUris']) ||
97
+ (0, configuration_1.readConfObject)(config, ['formatAbout', 'hideUris']);
98
+ const { pluginManager } = (0, util_1.getEnv)(session);
99
+ const confPostExt = pluginManager.evaluateExtensionPoint('Core-customizeAbout', {
100
+ config: {
101
+ ...conf,
102
+ ...(0, configuration_1.getConf)(session, ['formatAbout', 'config'], { config: conf }),
103
+ ...(0, configuration_1.readConfObject)(config, ['formatAbout', 'config'], { config: conf }),
104
+ },
105
+ }, { session, config });
106
+ const ExtraPanel = pluginManager.evaluateExtensionPoint('Core-extraAboutPanel', null, { session, config });
107
+ return (react_1.default.createElement(react_1.default.Fragment, null,
108
+ react_1.default.createElement(BaseFeatureDetail_1.BaseCard, { title: "Configuration" },
109
+ !hideUris ? (react_1.default.createElement(material_1.Button, { variant: "contained", style: { float: 'right' }, onClick: () => {
110
+ (0, copy_to_clipboard_1.default)(JSON.stringify(conf, null, 2));
111
+ setCopied(true);
112
+ setTimeout(() => setCopied(false), 1000);
113
+ } }, copied ? 'Copied to clipboard!' : 'Copy config')) : null,
114
+ react_1.default.createElement(BaseFeatureDetail_1.Attributes, { attributes: confPostExt, omit: ['displays', 'baseUri', 'refNames', 'formatAbout'], hideUris: hideUris })),
115
+ ExtraPanel ? (react_1.default.createElement(BaseFeatureDetail_1.BaseCard, { title: ExtraPanel.name },
116
+ react_1.default.createElement(ExtraPanel.Component, { config: config }))) : null,
117
+ react_1.default.createElement(FileInfo, { config: config })));
118
+ }
119
+ exports.AboutContents = AboutContents;
120
+ function AboutDialog({ config, handleClose, }) {
121
+ const { classes } = useStyles();
122
+ const session = (0, util_1.getSession)(config);
123
+ const trackName = (0, tracks_1.getTrackName)(config, session);
124
+ const { pluginManager } = (0, util_1.getEnv)(session);
125
+ const AboutComponent = pluginManager.evaluateExtensionPoint('Core-replaceAbout', AboutContents, { session, config });
97
126
  return (react_1.default.createElement(material_1.Dialog, { open: true, onClose: handleClose, maxWidth: "xl" },
98
127
  react_1.default.createElement(material_1.DialogTitle, null,
99
128
  trackName,
100
129
  react_1.default.createElement(material_1.IconButton, { className: classes.closeButton, onClick: () => handleClose(), size: "large" },
101
130
  react_1.default.createElement(Close_1.default, null))),
102
131
  react_1.default.createElement(material_1.DialogContent, { className: classes.content },
103
- react_1.default.createElement(BaseFeatureDetail_1.BaseCard, { title: "Configuration" },
104
- react_1.default.createElement(material_1.Button, { variant: "contained", style: { float: 'right' }, onClick: () => {
105
- (0, copy_to_clipboard_1.default)(JSON.stringify(conf, null, 2));
106
- setCopied(true);
107
- setTimeout(() => setCopied(false), 1000);
108
- } }, copied ? 'Copied to clipboard!' : 'Copy config'),
109
- react_1.default.createElement(BaseFeatureDetail_1.Attributes, { attributes: conf, omit: ['displays', 'baseUri', 'refNames'] })),
110
- info !== null ? (react_1.default.createElement(BaseFeatureDetail_1.BaseCard, { title: "File info" }, error ? (react_1.default.createElement(material_1.Typography, { color: "error" }, `${error}`)) : info === undefined ? ('Loading file data...') : (react_1.default.createElement(BaseFeatureDetail_1.Attributes, { attributes: details })))) : null)));
132
+ react_1.default.createElement(AboutComponent, { config: config }))));
111
133
  }
112
134
  exports.default = AboutDialog;
package/ui/App.d.ts CHANGED
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import { NotificationLevel, SessionWithDrawerWidgets, SnackAction } from '../util';
3
3
  import { MenuItem as JBMenuItem } from './index';
4
4
  declare type SnackbarMessage = [string, NotificationLevel, SnackAction];
5
- declare const App: ({ session, HeaderButtons, }: {
5
+ declare const App: (props: {
6
6
  HeaderButtons?: React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined;
7
7
  session: SessionWithDrawerWidgets & {
8
8
  savedSessionNames: string[];
package/ui/App.js CHANGED
@@ -30,12 +30,14 @@ const react_1 = __importStar(require("react"));
30
30
  const material_1 = require("@mui/material");
31
31
  const mui_1 = require("tss-react/mui");
32
32
  const Launch_1 = __importDefault(require("@mui/icons-material/Launch"));
33
+ const react_error_boundary_1 = require("react-error-boundary");
33
34
  const mobx_react_1 = require("mobx-react");
34
35
  const mobx_state_tree_1 = require("mobx-state-tree");
35
36
  // locals
36
37
  const configuration_1 = require("../configuration");
37
38
  const DrawerWidget_1 = __importDefault(require("./DrawerWidget"));
38
39
  const DropDownMenu_1 = __importDefault(require("./DropDownMenu"));
40
+ const ErrorMessage_1 = __importDefault(require("./ErrorMessage"));
39
41
  const EditableTypography_1 = __importDefault(require("./EditableTypography"));
40
42
  const Logo_1 = require("./Logo");
41
43
  const Snackbar_1 = __importDefault(require("./Snackbar"));
@@ -104,13 +106,9 @@ const Logo = (0, mobx_react_1.observer)(({ session }) => {
104
106
  return react_1.default.createElement("img", { src: logoPath.uri, alt: "Custom logo" });
105
107
  }
106
108
  });
107
- const App = (0, mobx_react_1.observer)(({ session, HeaderButtons = react_1.default.createElement("div", null), }) => {
108
- var _a;
109
+ const AppToolbar = (0, mobx_react_1.observer)(({ session, HeaderButtons = react_1.default.createElement("div", null), }) => {
109
110
  const { classes } = useStyles();
110
- const { pluginManager } = (0, mobx_state_tree_1.getEnv)(session);
111
- const viewTypes = pluginManager.getElementTypeRecord('view').all();
112
- const [value, setValue] = (0, react_1.useState)((_a = viewTypes[0]) === null || _a === void 0 ? void 0 : _a.name);
113
- const { visibleWidget, drawerWidth, minimized, activeWidgets, savedSessionNames, name, menus, views, drawerPosition, } = session;
111
+ const { savedSessionNames, name, menus } = session;
114
112
  function handleNameChange(newName) {
115
113
  if (savedSessionNames === null || savedSessionNames === void 0 ? void 0 : savedSessionNames.includes(newName)) {
116
114
  session.notify(`Cannot rename session to "${newName}", a saved session with that name already exists`, 'warning');
@@ -119,6 +117,48 @@ const App = (0, mobx_react_1.observer)(({ session, HeaderButtons = react_1.defau
119
117
  session.renameCurrentSession(newName);
120
118
  }
121
119
  }
120
+ return (react_1.default.createElement(material_1.Toolbar, null,
121
+ menus.map(menu => (react_1.default.createElement(DropDownMenu_1.default, { key: menu.label, menuTitle: menu.label, menuItems: menu.menuItems, session: session }))),
122
+ react_1.default.createElement("div", { className: classes.grow }),
123
+ react_1.default.createElement(material_1.Tooltip, { title: "Rename Session", arrow: true },
124
+ react_1.default.createElement(EditableTypography_1.default, { value: name, setValue: handleNameChange, variant: "body1", classes: {
125
+ inputBase: classes.inputBase,
126
+ inputRoot: classes.inputRoot,
127
+ inputFocused: classes.inputFocused,
128
+ } })),
129
+ HeaderButtons,
130
+ react_1.default.createElement("div", { className: classes.grow }),
131
+ react_1.default.createElement("div", { style: { width: 150, maxHeight: 48 } },
132
+ react_1.default.createElement(Logo, { session: session }))));
133
+ });
134
+ const ViewLauncher = (0, mobx_react_1.observer)(({ session }) => {
135
+ var _a;
136
+ const { classes } = useStyles();
137
+ const { pluginManager } = (0, mobx_state_tree_1.getEnv)(session);
138
+ const viewTypes = pluginManager.getElementTypeRecord('view').all();
139
+ const [value, setValue] = (0, react_1.useState)((_a = viewTypes[0]) === null || _a === void 0 ? void 0 : _a.name);
140
+ return (react_1.default.createElement(material_1.Paper, { className: classes.selectPaper },
141
+ react_1.default.createElement(material_1.Typography, null, "Select a view to launch"),
142
+ react_1.default.createElement(material_1.Select, { value: value, onChange: event => setValue(event.target.value) }, viewTypes.map(({ name }) => (react_1.default.createElement(material_1.MenuItem, { key: name, value: name }, name)))),
143
+ react_1.default.createElement(material_1.Button, { onClick: () => {
144
+ session.addView(value, {});
145
+ }, variant: "contained", color: "primary" }, "Launch view")));
146
+ });
147
+ const ViewPanel = (0, mobx_react_1.observer)(({ view, session }) => {
148
+ const { pluginManager } = (0, mobx_state_tree_1.getEnv)(session);
149
+ const viewType = pluginManager.getViewType(view.type);
150
+ if (!viewType) {
151
+ throw new Error(`unknown view type ${view.type}`);
152
+ }
153
+ const { ReactComponent } = viewType;
154
+ return (react_1.default.createElement(ViewContainer_1.default, { view: view, onClose: () => session.removeView(view) },
155
+ react_1.default.createElement(react_1.Suspense, { fallback: react_1.default.createElement("div", null, "Loading...") },
156
+ react_1.default.createElement(ReactComponent, { model: view, session: session, getTrackType: pluginManager.getTrackType }))));
157
+ });
158
+ const App = (0, mobx_react_1.observer)((props) => {
159
+ const { session } = props;
160
+ const { classes } = useStyles();
161
+ const { minimized, visibleWidget, drawerWidth, activeWidgets, views, drawerPosition, } = session;
122
162
  const drawerVisible = visibleWidget && !minimized;
123
163
  let grid;
124
164
  if (drawerPosition === 'right') {
@@ -142,43 +182,10 @@ const App = (0, mobx_react_1.observer)(({ session, HeaderButtons = react_1.defau
142
182
  react_1.default.createElement("div", { className: classes.menuBarAndComponents },
143
183
  react_1.default.createElement("div", { className: classes.menuBar },
144
184
  react_1.default.createElement(material_1.AppBar, { className: classes.appBar, position: "static" },
145
- react_1.default.createElement(material_1.Toolbar, null,
146
- menus.map(menu => (react_1.default.createElement(DropDownMenu_1.default, { key: menu.label, menuTitle: menu.label, menuItems: menu.menuItems, session: session }))),
147
- react_1.default.createElement("div", { className: classes.grow }),
148
- react_1.default.createElement(material_1.Tooltip, { title: "Rename Session", arrow: true },
149
- react_1.default.createElement(EditableTypography_1.default, { value: name, setValue: handleNameChange, variant: "body1", classes: {
150
- inputBase: classes.inputBase,
151
- inputRoot: classes.inputRoot,
152
- inputFocused: classes.inputFocused,
153
- } })),
154
- HeaderButtons,
155
- react_1.default.createElement("div", { className: classes.grow }),
156
- react_1.default.createElement("div", { style: { width: 150, maxHeight: 48 } },
157
- react_1.default.createElement(Logo, { session: session }))))),
185
+ react_1.default.createElement(AppToolbar, { ...props }))),
158
186
  react_1.default.createElement("div", { className: classes.components },
159
- views.length ? (views.map(view => {
160
- const viewType = pluginManager.getViewType(view.type);
161
- if (!viewType) {
162
- throw new Error(`unknown view type ${view.type}`);
163
- }
164
- const { ReactComponent } = viewType;
165
- return (react_1.default.createElement(ViewContainer_1.default, { key: `view-${view.id}`, view: view, onClose: () => {
166
- session.removeView(view);
167
- session.notify(`A view has been closed`, 'info', {
168
- name: 'undo',
169
- onClick: () => {
170
- pluginManager.rootModel.history.undo();
171
- },
172
- });
173
- } },
174
- react_1.default.createElement(react_1.Suspense, { fallback: react_1.default.createElement("div", null, "Loading...") },
175
- react_1.default.createElement(ReactComponent, { model: view, session: session, getTrackType: pluginManager.getTrackType }))));
176
- })) : (react_1.default.createElement(material_1.Paper, { className: classes.selectPaper },
177
- react_1.default.createElement(material_1.Typography, null, "Select a view to launch"),
178
- react_1.default.createElement(material_1.Select, { value: value, onChange: event => setValue(event.target.value) }, viewTypes.map(({ name }) => (react_1.default.createElement(material_1.MenuItem, { key: name, value: name }, name)))),
179
- react_1.default.createElement(material_1.Button, { onClick: () => {
180
- session.addView(value, {});
181
- }, variant: "contained", color: "primary" }, "Launch view"))),
187
+ views.length ? (views.map(view => (react_1.default.createElement(react_error_boundary_1.ErrorBoundary, { key: `view-${view.id}`, FallbackComponent: ({ error }) => (react_1.default.createElement(ErrorMessage_1.default, { error: error })) },
188
+ react_1.default.createElement(ViewPanel, { view: view, session: session }))))) : (react_1.default.createElement(ViewLauncher, { ...props })),
182
189
  react_1.default.createElement("div", { style: { height: 300 } }))),
183
190
  activeWidgets.size > 0 && minimized ? (react_1.default.createElement(material_1.Tooltip, { title: "Open drawer widget" },
184
191
  react_1.default.createElement(material_1.Fab, { className: drawerPosition === 'right' ? classes.fabRight : classes.fabLeft, color: "primary", "data-testid": "drawer-maximize", onClick: () => session.showWidgetDrawer() },
@@ -27,10 +27,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
29
  const react_1 = __importStar(require("react"));
30
+ const react_error_boundary_1 = require("react-error-boundary");
30
31
  const material_1 = require("@mui/material");
31
32
  const mui_1 = require("tss-react/mui");
32
33
  const mobx_react_1 = require("mobx-react");
33
- const mobx_state_tree_1 = require("mobx-state-tree");
34
+ const util_1 = require("../util");
34
35
  // icons
35
36
  const Delete_1 = __importDefault(require("@mui/icons-material/Delete"));
36
37
  const Close_1 = __importDefault(require("@mui/icons-material/Close"));
@@ -38,6 +39,7 @@ const Minimize_1 = __importDefault(require("@mui/icons-material/Minimize"));
38
39
  const MoreVert_1 = __importDefault(require("@mui/icons-material/MoreVert"));
39
40
  // locals
40
41
  const Drawer_1 = __importDefault(require("./Drawer"));
42
+ const ErrorMessage_1 = __importDefault(require("./ErrorMessage"));
41
43
  const useStyles = (0, mui_1.makeStyles)()(theme => ({
42
44
  formControl: {
43
45
  margin: 0,
@@ -57,10 +59,10 @@ const useStyles = (0, mui_1.makeStyles)()(theme => ({
57
59
  },
58
60
  }));
59
61
  const DrawerHeader = (0, mobx_react_1.observer)(({ session, setToolbarHeight, }) => {
60
- const { pluginManager } = (0, mobx_state_tree_1.getEnv)(session);
62
+ const { pluginManager } = (0, util_1.getEnv)(session);
61
63
  const { visibleWidget, activeWidgets, drawerPosition } = session;
62
64
  const { classes } = useStyles();
63
- const [anchorEl, setAnchorEl] = react_1.default.useState(null);
65
+ const [anchorEl, setAnchorEl] = (0, react_1.useState)(null);
64
66
  return (react_1.default.createElement(material_1.AppBar, { position: "sticky", className: classes.header, ref: ref => setToolbarHeight((ref === null || ref === void 0 ? void 0 : ref.getBoundingClientRect().height) || 0) },
65
67
  react_1.default.createElement(material_1.Toolbar, { disableGutters: true },
66
68
  react_1.default.createElement(material_1.FormControl, { className: classes.formControl },
@@ -108,9 +110,12 @@ const DrawerHeader = (0, mobx_react_1.observer)(({ session, setToolbarHeight, })
108
110
  });
109
111
  const DrawerWidget = (0, mobx_react_1.observer)(({ session }) => {
110
112
  const { visibleWidget } = session;
111
- const { pluginManager } = (0, mobx_state_tree_1.getEnv)(session);
113
+ const { pluginManager } = (0, util_1.getEnv)(session);
112
114
  const DrawerComponent = visibleWidget
113
- ? pluginManager.getWidgetType(visibleWidget.type).ReactComponent
115
+ ? pluginManager.evaluateExtensionPoint('Core-replaceWidget', pluginManager.getWidgetType(visibleWidget.type).ReactComponent, {
116
+ session,
117
+ model: visibleWidget,
118
+ })
114
119
  : null;
115
120
  // we track the toolbar height because components that use virtualized
116
121
  // height want to be able to fill the contained, minus the toolbar height
@@ -119,6 +124,6 @@ const DrawerWidget = (0, mobx_react_1.observer)(({ session }) => {
119
124
  return (react_1.default.createElement(Drawer_1.default, { session: session },
120
125
  react_1.default.createElement(DrawerHeader, { session: session, setToolbarHeight: setToolbarHeight }),
121
126
  react_1.default.createElement(react_1.Suspense, { fallback: react_1.default.createElement("div", null, "Loading...") },
122
- react_1.default.createElement(DrawerComponent, { model: visibleWidget, session: session, toolbarHeight: toolbarHeight }))));
127
+ react_1.default.createElement(react_error_boundary_1.ErrorBoundary, { FallbackComponent: ({ error }) => react_1.default.createElement(ErrorMessage_1.default, { error: error }) }, DrawerComponent ? (react_1.default.createElement(DrawerComponent, { model: visibleWidget, session: session, toolbarHeight: toolbarHeight })) : null))));
123
128
  });
124
129
  exports.default = DrawerWidget;
@@ -1,24 +1,8 @@
1
1
  /// <reference types="react" />
2
- import PropTypes from 'prop-types';
3
- declare const FatalErrorDialog: {
4
- ({ componentStack, error, onFactoryReset, resetButtonText, }: {
5
- componentStack: string;
6
- error: Error;
7
- onFactoryReset: Function;
8
- resetButtonText: string;
9
- }): JSX.Element;
10
- propTypes: {
11
- componentStack: PropTypes.Requireable<string>;
12
- error: PropTypes.Requireable<PropTypes.InferProps<{}>>;
13
- onFactoryReset: PropTypes.Validator<(...args: any[]) => any>;
14
- resetButtonText: PropTypes.Requireable<string>;
15
- };
16
- defaultProps: {
17
- error: {
18
- message: string;
19
- };
20
- componentStack: string;
21
- resetButtonText: string;
22
- };
23
- };
2
+ declare const FatalErrorDialog: ({ componentStack, error, onFactoryReset, resetButtonText, }: {
3
+ componentStack?: string | undefined;
4
+ error?: unknown;
5
+ onFactoryReset: Function;
6
+ resetButtonText?: string | undefined;
7
+ }) => JSX.Element;
24
8
  export default FatalErrorDialog;
@@ -26,44 +26,25 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
- const Button_1 = __importDefault(require("@mui/material/Button"));
30
- const Dialog_1 = __importDefault(require("@mui/material/Dialog"));
31
- const DialogActions_1 = __importDefault(require("@mui/material/DialogActions"));
32
- const DialogContent_1 = __importDefault(require("@mui/material/DialogContent"));
33
- const DialogTitle_1 = __importDefault(require("@mui/material/DialogTitle"));
34
- const prop_types_1 = __importDefault(require("prop-types"));
35
29
  const react_1 = __importStar(require("react"));
30
+ const material_1 = require("@mui/material");
36
31
  const FactoryResetDialog_1 = __importDefault(require("./FactoryResetDialog"));
37
32
  const ResetComponent = ({ onFactoryReset, resetButtonText, }) => {
38
33
  const [dialogOpen, setDialogOpen] = (0, react_1.useState)(false);
39
34
  return (react_1.default.createElement(react_1.default.Fragment, null,
40
- react_1.default.createElement(Button_1.default, { "data-testid": "fatal-error", color: "primary", variant: "contained", onClick: () => setDialogOpen(true) }, resetButtonText),
35
+ react_1.default.createElement(material_1.Button, { "data-testid": "fatal-error", color: "primary", variant: "contained", onClick: () => setDialogOpen(true) }, resetButtonText),
41
36
  react_1.default.createElement(FactoryResetDialog_1.default, { onClose: () => setDialogOpen(false), open: dialogOpen, onFactoryReset: onFactoryReset })));
42
37
  };
43
- ResetComponent.propTypes = {
44
- onFactoryReset: prop_types_1.default.func.isRequired,
45
- resetButtonText: prop_types_1.default.string.isRequired,
46
- };
47
- const FatalErrorDialog = ({ componentStack, error, onFactoryReset, resetButtonText, }) => {
48
- return (react_1.default.createElement(Dialog_1.default, { open: true },
49
- react_1.default.createElement(DialogTitle_1.default, { style: { backgroundColor: '#e88' } }, "Fatal error"),
50
- react_1.default.createElement(DialogContent_1.default, null,
38
+ const FatalErrorDialog = ({ componentStack, error = 'No error message provided', onFactoryReset, resetButtonText = 'Factory Reset', }) => {
39
+ console.error(error);
40
+ return (react_1.default.createElement(material_1.Dialog, { open: true },
41
+ react_1.default.createElement(material_1.DialogTitle, { style: { background: '#e88' } }, "Fatal error"),
42
+ react_1.default.createElement(material_1.DialogContent, null,
51
43
  react_1.default.createElement("pre", null,
52
- error.toString(),
44
+ `${error}`,
53
45
  componentStack)),
54
- react_1.default.createElement(DialogActions_1.default, null,
55
- react_1.default.createElement(Button_1.default, { color: "secondary", variant: "contained", onClick: () => window.location.reload() }, "Refresh"),
46
+ react_1.default.createElement(material_1.DialogActions, null,
47
+ react_1.default.createElement(material_1.Button, { color: "secondary", variant: "contained", onClick: () => window.location.reload() }, "Refresh"),
56
48
  react_1.default.createElement(ResetComponent, { onFactoryReset: onFactoryReset, resetButtonText: resetButtonText }))));
57
49
  };
58
- FatalErrorDialog.propTypes = {
59
- componentStack: prop_types_1.default.string,
60
- error: prop_types_1.default.shape({}),
61
- onFactoryReset: prop_types_1.default.func.isRequired,
62
- resetButtonText: prop_types_1.default.string,
63
- };
64
- FatalErrorDialog.defaultProps = {
65
- error: { message: 'No error message provided' },
66
- componentStack: '',
67
- resetButtonText: 'Factory Reset',
68
- };
69
50
  exports.default = FatalErrorDialog;
package/ui/theme.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { ThemeOptions } from '@mui/material/styles';
1
2
  import type { PaletteOptions } from '@mui/material/styles/createPalette';
2
3
  declare module '@mui/material/styles/createPalette' {
3
4
  interface Palette {
@@ -43,7 +44,7 @@ export declare function createJBrowseDefaultProps(): {
43
44
  components: {
44
45
  MuiButton: {
45
46
  defaultProps: {
46
- size: string;
47
+ size: "small";
47
48
  };
48
49
  };
49
50
  MuiAccordion: {
@@ -56,43 +57,43 @@ export declare function createJBrowseDefaultProps(): {
56
57
  };
57
58
  MuiFilledInput: {
58
59
  defaultProps: {
59
- margin: string;
60
+ margin: "dense";
60
61
  };
61
62
  };
62
63
  MuiFormControl: {
63
64
  defaultProps: {
64
- margin: string;
65
- size: string;
65
+ margin: "dense";
66
+ size: "small";
66
67
  };
67
68
  };
68
69
  MuiFormHelperText: {
69
70
  defaultProps: {
70
- margin: string;
71
+ margin: "dense";
71
72
  };
72
73
  };
73
74
  MuiIconButton: {
74
75
  defaultProps: {
75
- size: string;
76
+ size: "small";
76
77
  };
77
78
  };
78
79
  MuiInputBase: {
79
80
  defaultProps: {
80
- margin: string;
81
+ margin: "dense";
81
82
  };
82
83
  };
83
84
  MuiAutocomplete: {
84
85
  defaultProps: {
85
- size: string;
86
+ size: "small";
86
87
  };
87
88
  };
88
89
  MuiInputLabel: {
89
90
  defaultProps: {
90
- margin: string;
91
+ margin: "dense";
91
92
  };
92
93
  };
93
94
  MuiToolbar: {
94
95
  defaultProps: {
95
- variant: string;
96
+ variant: "dense";
96
97
  };
97
98
  };
98
99
  MuiListItem: {
@@ -102,17 +103,17 @@ export declare function createJBrowseDefaultProps(): {
102
103
  };
103
104
  MuiOutlinedInput: {
104
105
  defaultProps: {
105
- margin: string;
106
+ margin: "dense";
106
107
  };
107
108
  };
108
109
  MuiFab: {
109
110
  defaultProps: {
110
- size: string;
111
+ size: "small";
111
112
  };
112
113
  };
113
114
  MuiTable: {
114
115
  defaultProps: {
115
- size: string;
116
+ size: "small";
116
117
  };
117
118
  };
118
119
  MuiMenuList: {
@@ -127,8 +128,8 @@ export declare function createJBrowseDefaultProps(): {
127
128
  };
128
129
  MuiTextField: {
129
130
  defaultProps: {
130
- margin: string;
131
- variant: string;
131
+ margin: "dense";
132
+ variant: "standard";
132
133
  };
133
134
  };
134
135
  };
@@ -175,159 +176,5 @@ export declare function createJBrowseDefaultOverrides(palette?: PaletteOptions):
175
176
  };
176
177
  };
177
178
  };
178
- export declare const jbrowseBaseTheme: {
179
- components: {
180
- MuiButton: {
181
- defaultProps: {
182
- size: string;
183
- };
184
- };
185
- MuiAccordion: {
186
- defaultProps: {
187
- disableGutters: boolean;
188
- TransitionProps: {
189
- timeout: number;
190
- };
191
- };
192
- };
193
- MuiFilledInput: {
194
- defaultProps: {
195
- margin: string;
196
- };
197
- };
198
- MuiFormControl: {
199
- defaultProps: {
200
- margin: string;
201
- size: string;
202
- };
203
- };
204
- MuiFormHelperText: {
205
- defaultProps: {
206
- margin: string;
207
- };
208
- };
209
- MuiIconButton: {
210
- defaultProps: {
211
- size: string;
212
- };
213
- };
214
- MuiInputBase: {
215
- defaultProps: {
216
- margin: string;
217
- };
218
- };
219
- MuiAutocomplete: {
220
- defaultProps: {
221
- size: string;
222
- };
223
- };
224
- MuiInputLabel: {
225
- defaultProps: {
226
- margin: string;
227
- };
228
- };
229
- MuiToolbar: {
230
- defaultProps: {
231
- variant: string;
232
- };
233
- };
234
- MuiListItem: {
235
- defaultProps: {
236
- dense: boolean;
237
- };
238
- };
239
- MuiOutlinedInput: {
240
- defaultProps: {
241
- margin: string;
242
- };
243
- };
244
- MuiFab: {
245
- defaultProps: {
246
- size: string;
247
- };
248
- };
249
- MuiTable: {
250
- defaultProps: {
251
- size: string;
252
- };
253
- };
254
- MuiMenuList: {
255
- defaultProps: {
256
- dense: boolean;
257
- };
258
- };
259
- MuiMenuItem: {
260
- defaultProps: {
261
- dense: boolean;
262
- };
263
- };
264
- MuiTextField: {
265
- defaultProps: {
266
- margin: string;
267
- variant: string;
268
- };
269
- };
270
- } & {
271
- MuiIconButton: {
272
- styleOverrides: {
273
- colorSecondary: {
274
- color: string;
275
- };
276
- };
277
- };
278
- MuiButton: {
279
- styleOverrides: {
280
- textSecondary: {
281
- color: string;
282
- };
283
- };
284
- };
285
- MuiFab: {
286
- styleOverrides: {
287
- secondary: {
288
- backgroundColor: string;
289
- };
290
- };
291
- };
292
- MuiLink: {
293
- styleOverrides: {
294
- root: {
295
- color: string;
296
- };
297
- };
298
- };
299
- MuiAccordionSummary: {
300
- styleOverrides: {
301
- root: {
302
- backgroundColor: string;
303
- };
304
- content: {
305
- color: string;
306
- };
307
- };
308
- };
309
- };
310
- palette: {
311
- primary: {
312
- main: string;
313
- };
314
- secondary: {
315
- main: string;
316
- };
317
- tertiary: import("@mui/material/styles").PaletteColor;
318
- quaternary: import("@mui/material/styles").PaletteColor;
319
- stopCodon: string;
320
- startCodon: string;
321
- bases: {
322
- A: import("@mui/material/styles").PaletteColor;
323
- C: import("@mui/material/styles").PaletteColor;
324
- G: import("@mui/material/styles").PaletteColor;
325
- T: import("@mui/material/styles").PaletteColor;
326
- };
327
- };
328
- typography: {
329
- fontSize: number;
330
- };
331
- spacing: number;
332
- };
333
- export declare function createJBrowseTheme(theme?: any): import("@mui/material/styles").Theme;
179
+ export declare function createJBrowseBaseTheme(palette?: PaletteOptions): ThemeOptions;
180
+ export declare function createJBrowseTheme(theme?: ThemeOptions): import("@mui/material/styles").Theme;