@jbrowse/core 2.2.0 → 2.2.2

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 (80) hide show
  1. package/BaseFeatureWidget/BaseFeatureDetail.d.ts +1 -0
  2. package/BaseFeatureWidget/BaseFeatureDetail.js +43 -28
  3. package/BaseFeatureWidget/SequenceBox.js +4 -8
  4. package/BaseFeatureWidget/SequenceFeatureDetails.js +1 -0
  5. package/BaseFeatureWidget/SequenceFeatureSettingsDialog.js +2 -17
  6. package/BaseFeatureWidget/SequenceHelpDialog.js +3 -19
  7. package/Plugin.d.ts +1 -1
  8. package/PluginLoader.d.ts +2 -2
  9. package/PluginManager.d.ts +3 -3
  10. package/assemblyManager/assembly.d.ts +3 -3
  11. package/assemblyManager/assembly.js +1 -1
  12. package/configuration/configurationSchema.d.ts +2 -2
  13. package/data_adapters/BaseAdapter.d.ts +3 -3
  14. package/data_adapters/dataAdapterCache.d.ts +1 -1
  15. package/package.json +2 -2
  16. package/pluggableElementTypes/AdapterType.d.ts +1 -1
  17. package/pluggableElementTypes/AddTrackWorkflowType.d.ts +2 -2
  18. package/pluggableElementTypes/RpcMethodType.d.ts +1 -1
  19. package/pluggableElementTypes/ViewType.d.ts +2 -2
  20. package/pluggableElementTypes/index.d.ts +2 -2
  21. package/pluggableElementTypes/models/BaseConnectionModelFactory.d.ts +23 -2
  22. package/pluggableElementTypes/models/BaseConnectionModelFactory.js +24 -2
  23. package/pluggableElementTypes/models/BaseDisplayModel.d.ts +2 -2
  24. package/pluggableElementTypes/models/BaseTrackModel.d.ts +49 -4
  25. package/pluggableElementTypes/models/BaseTrackModel.js +77 -26
  26. package/pluggableElementTypes/models/BaseViewModel.d.ts +22 -0
  27. package/pluggableElementTypes/models/BaseViewModel.js +41 -2
  28. package/pluggableElementTypes/models/InternetAccountModel.d.ts +53 -6
  29. package/pluggableElementTypes/models/InternetAccountModel.js +57 -6
  30. package/pluggableElementTypes/models/baseInternetAccountConfig.d.ts +0 -3
  31. package/pluggableElementTypes/models/baseTrackConfig.d.ts +2 -2
  32. package/pluggableElementTypes/models/baseTrackConfig.js +9 -0
  33. package/pluggableElementTypes/renderers/BoxRendererType.d.ts +1 -1
  34. package/pluggableElementTypes/renderers/ComparativeServerSideRendererType.d.ts +1 -1
  35. package/pluggableElementTypes/renderers/RendererType.d.ts +1 -1
  36. package/pluggableElementTypes/renderers/ServerSideRendererType.d.ts +2 -2
  37. package/pluggableElementTypes/renderers/ServerSideRendererType.js +1 -1
  38. package/pluggableElementTypes/renderers/util/serializableFilterChain.d.ts +2 -2
  39. package/rpc/BaseRpcDriver.js +1 -1
  40. package/rpc/RpcManager.d.ts +2 -2
  41. package/rpc/remoteAbortSignals.d.ts +1 -1
  42. package/tsconfig.build.tsbuildinfo +1 -1
  43. package/ui/AboutDialog.d.ts +1 -1
  44. package/ui/AboutDialog.js +8 -18
  45. package/ui/App.d.ts +2 -2
  46. package/ui/App.js +6 -8
  47. package/ui/AssemblySelector.d.ts +1 -1
  48. package/ui/AssemblySelector.js +12 -10
  49. package/ui/Dialog.d.ts +7 -0
  50. package/ui/Dialog.js +35 -0
  51. package/ui/EditableTypography.d.ts +4 -4
  52. package/ui/EditableTypography.js +7 -11
  53. package/ui/FactoryResetDialog.js +8 -13
  54. package/ui/Logo.d.ts +1 -1
  55. package/ui/Menu.d.ts +2 -2
  56. package/ui/ReturnToImportFormDialog.js +2 -17
  57. package/ui/Snackbar.d.ts +1 -1
  58. package/ui/ViewContainer.d.ts +2 -1
  59. package/ui/ViewContainer.js +34 -22
  60. package/ui/index.d.ts +1 -0
  61. package/ui/index.js +3 -1
  62. package/util/Base1DViewModel.d.ts +72 -2
  63. package/util/Base1DViewModel.js +94 -3
  64. package/util/analytics.js +3 -0
  65. package/util/blockTypes.d.ts +1 -1
  66. package/util/formatFastaStrings.d.ts +1 -1
  67. package/util/formatFastaStrings.js +1 -1
  68. package/util/index.d.ts +3 -1
  69. package/util/index.js +13 -3
  70. package/util/io/RemoteFileWithRangeCache.js +2 -2
  71. package/util/io/index.js +3 -3
  72. package/util/jexl.d.ts +1 -1
  73. package/util/layouts/BaseLayout.d.ts +1 -1
  74. package/util/offscreenCanvasPonyfill.d.ts +2 -2
  75. package/util/offscreenCanvasUtils.d.ts +1 -1
  76. package/util/tracks.d.ts +3 -3
  77. package/util/tracks.js +1 -1
  78. package/util/types/index.d.ts +15 -8
  79. package/util/types/index.js +8 -1
  80. package/util/types/util.d.ts +5 -5
@@ -1,6 +1,6 @@
1
1
  /// <reference types="react" />
2
2
  import { AnyConfigurationModel } from '../configuration';
3
- export declare function FileInfo({ config }: {
3
+ export declare function FileInfoPanel({ config }: {
4
4
  config: AnyConfigurationModel;
5
5
  }): JSX.Element | null;
6
6
  export declare function AboutContents({ config }: {
package/ui/AboutDialog.js CHANGED
@@ -26,29 +26,23 @@ 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
+ exports.AboutContents = exports.FileInfoPanel = void 0;
30
30
  const react_1 = __importStar(require("react"));
31
31
  const copy_to_clipboard_1 = __importDefault(require("copy-to-clipboard"));
32
32
  const material_1 = require("@mui/material");
33
- const Close_1 = __importDefault(require("@mui/icons-material/Close"));
34
33
  const mui_1 = require("tss-react/mui");
35
34
  const configuration_1 = require("../configuration");
35
+ const Dialog_1 = __importDefault(require("./Dialog"));
36
36
  const LoadingEllipses_1 = __importDefault(require("./LoadingEllipses"));
37
37
  const util_1 = require("../util");
38
38
  const tracks_1 = require("../util/tracks");
39
39
  const BaseFeatureDetail_1 = require("../BaseFeatureWidget/BaseFeatureDetail");
40
- const useStyles = (0, mui_1.makeStyles)()(theme => ({
41
- closeButton: {
42
- position: 'absolute',
43
- right: theme.spacing(1),
44
- top: theme.spacing(1),
45
- color: theme.palette.grey[500],
46
- },
40
+ const useStyles = (0, mui_1.makeStyles)()({
47
41
  content: {
48
42
  minWidth: 800,
49
43
  },
50
- }));
51
- function FileInfo({ config }) {
44
+ });
45
+ function FileInfoPanel({ config }) {
52
46
  const [error, setError] = (0, react_1.useState)();
53
47
  const [info, setInfo] = (0, react_1.useState)();
54
48
  const session = (0, util_1.getSession)(config);
@@ -89,7 +83,7 @@ function FileInfo({ config }) {
89
83
  : info || {};
90
84
  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 ? (react_1.default.createElement(LoadingEllipses_1.default, { message: "Loading file data" })) : (react_1.default.createElement(BaseFeatureDetail_1.Attributes, { attributes: details })))) : null;
91
85
  }
92
- exports.FileInfo = FileInfo;
86
+ exports.FileInfoPanel = FileInfoPanel;
93
87
  function AboutContents({ config }) {
94
88
  const [copied, setCopied] = (0, react_1.useState)(false);
95
89
  const conf = (0, configuration_1.readConfObject)(config);
@@ -115,7 +109,7 @@ function AboutContents({ config }) {
115
109
  react_1.default.createElement(BaseFeatureDetail_1.Attributes, { attributes: confPostExt, omit: ['displays', 'baseUri', 'refNames', 'formatAbout'], hideUris: hideUris })),
116
110
  ExtraPanel ? (react_1.default.createElement(BaseFeatureDetail_1.BaseCard, { title: ExtraPanel.name },
117
111
  react_1.default.createElement(ExtraPanel.Component, { config: config }))) : null,
118
- react_1.default.createElement(FileInfo, { config: config })));
112
+ react_1.default.createElement(FileInfoPanel, { config: config })));
119
113
  }
120
114
  exports.AboutContents = AboutContents;
121
115
  function AboutDialog({ config, handleClose, }) {
@@ -124,11 +118,7 @@ function AboutDialog({ config, handleClose, }) {
124
118
  const trackName = (0, tracks_1.getTrackName)(config, session);
125
119
  const { pluginManager } = (0, util_1.getEnv)(session);
126
120
  const AboutComponent = pluginManager.evaluateExtensionPoint('Core-replaceAbout', AboutContents, { session, config });
127
- return (react_1.default.createElement(material_1.Dialog, { open: true, onClose: handleClose, maxWidth: "xl" },
128
- react_1.default.createElement(material_1.DialogTitle, null,
129
- trackName,
130
- react_1.default.createElement(material_1.IconButton, { className: classes.closeButton, onClick: () => handleClose(), size: "large" },
131
- react_1.default.createElement(Close_1.default, null))),
121
+ return (react_1.default.createElement(Dialog_1.default, { open: true, onClose: handleClose, title: trackName, maxWidth: "xl" },
132
122
  react_1.default.createElement(material_1.DialogContent, { className: classes.content },
133
123
  react_1.default.createElement(AboutComponent, { config: config }))));
134
124
  }
package/ui/App.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import { NotificationLevel, SessionWithDrawerWidgets, SnackAction } from '../util';
3
- import { MenuItem as JBMenuItem } from './index';
4
- declare type SnackbarMessage = [string, NotificationLevel, SnackAction];
3
+ import { MenuItem as JBMenuItem } from './Menu';
4
+ type SnackbarMessage = [string, NotificationLevel, SnackAction];
5
5
  declare const App: (props: {
6
6
  HeaderButtons?: React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined;
7
7
  session: SessionWithDrawerWidgets & {
package/ui/App.js CHANGED
@@ -35,14 +35,15 @@ const mobx_react_1 = require("mobx-react");
35
35
  const mobx_state_tree_1 = require("mobx-state-tree");
36
36
  // locals
37
37
  const configuration_1 = require("../configuration");
38
+ // ui elements
38
39
  const DrawerWidget_1 = __importDefault(require("./DrawerWidget"));
39
40
  const DropDownMenu_1 = __importDefault(require("./DropDownMenu"));
40
41
  const ErrorMessage_1 = __importDefault(require("./ErrorMessage"));
41
42
  const LoadingEllipses_1 = __importDefault(require("./LoadingEllipses"));
42
43
  const EditableTypography_1 = __importDefault(require("./EditableTypography"));
43
- const Logo_1 = require("./Logo");
44
44
  const Snackbar_1 = __importDefault(require("./Snackbar"));
45
45
  const ViewContainer_1 = __importDefault(require("./ViewContainer"));
46
+ const Logo_1 = require("./Logo");
46
47
  const useStyles = (0, mui_1.makeStyles)()(theme => ({
47
48
  root: {
48
49
  fontFamily: 'Roboto',
@@ -143,9 +144,7 @@ const ViewLauncher = (0, mobx_react_1.observer)(({ session }) => {
143
144
  react_1.default.createElement(material_1.FormControl, { style: { margin: 2 } },
144
145
  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))))),
145
146
  react_1.default.createElement(material_1.FormControl, { style: { margin: 2 } },
146
- react_1.default.createElement(material_1.Button, { onClick: () => {
147
- session.addView(value, {});
148
- }, variant: "contained", color: "primary" }, "Launch view"))));
147
+ react_1.default.createElement(material_1.Button, { onClick: () => session.addView(value, {}), variant: "contained", color: "primary" }, "Launch view"))));
149
148
  });
150
149
  const ViewPanel = (0, mobx_react_1.observer)(({ view, session }) => {
151
150
  const { pluginManager } = (0, mobx_state_tree_1.getEnv)(session);
@@ -154,9 +153,9 @@ const ViewPanel = (0, mobx_react_1.observer)(({ view, session }) => {
154
153
  throw new Error(`unknown view type ${view.type}`);
155
154
  }
156
155
  const { ReactComponent } = viewType;
157
- return (react_1.default.createElement(ViewContainer_1.default, { view: view, onClose: () => session.removeView(view) },
156
+ 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 }) },
158
157
  react_1.default.createElement(react_1.Suspense, { fallback: react_1.default.createElement(LoadingEllipses_1.default, null) },
159
- react_1.default.createElement(ReactComponent, { model: view, session: session, getTrackType: pluginManager.getTrackType }))));
158
+ react_1.default.createElement(ReactComponent, { model: view, session: session, getTrackType: pluginManager.getTrackType })))) : (false)));
160
159
  });
161
160
  const App = (0, mobx_react_1.observer)((props) => {
162
161
  const { session } = props;
@@ -187,8 +186,7 @@ const App = (0, mobx_react_1.observer)((props) => {
187
186
  react_1.default.createElement(material_1.AppBar, { className: classes.appBar, position: "static" },
188
187
  react_1.default.createElement(AppToolbar, { ...props }))),
189
188
  react_1.default.createElement("div", { className: classes.components },
190
- 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 })) },
191
- react_1.default.createElement(ViewPanel, { view: view, session: session }))))) : (react_1.default.createElement(ViewLauncher, { ...props })),
189
+ views.length ? (views.map(view => (react_1.default.createElement(ViewPanel, { key: `view-${view.id}`, view: view, session: session })))) : (react_1.default.createElement(ViewLauncher, { ...props })),
192
190
  react_1.default.createElement("div", { style: { height: 300 } }))),
193
191
  activeWidgets.size > 0 && minimized ? (react_1.default.createElement(material_1.Tooltip, { title: "Open drawer widget" },
194
192
  react_1.default.createElement(material_1.Fab, { className: drawerPosition === 'right' ? classes.fabRight : classes.fabLeft, color: "primary", "data-testid": "drawer-maximize", onClick: () => session.showWidgetDrawer() },
@@ -4,7 +4,7 @@ import { AbstractSessionModel } from '../util';
4
4
  declare const AssemblySelector: ({ session, onChange, selected, InputProps, extra, }: {
5
5
  session: AbstractSessionModel;
6
6
  onChange: (arg: string) => void;
7
- selected: string | undefined;
7
+ selected?: string | undefined;
8
8
  InputProps?: IIP | undefined;
9
9
  extra?: unknown;
10
10
  }) => JSX.Element;
@@ -24,28 +24,30 @@ var __importStar = (this && this.__importStar) || function (mod) {
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
26
  const react_1 = __importStar(require("react"));
27
- const mobx_react_1 = require("mobx-react");
28
27
  const material_1 = require("@mui/material");
29
- const util_1 = require("@jbrowse/core/util");
28
+ const mobx_react_1 = require("mobx-react");
30
29
  const mui_1 = require("tss-react/mui");
31
30
  // locals
32
31
  const configuration_1 = require("../configuration");
33
- const useStyles = (0, mui_1.makeStyles)()(() => ({
32
+ const util_1 = require("../util");
33
+ const useStyles = (0, mui_1.makeStyles)()({
34
34
  importFormEntry: {
35
35
  minWidth: 180,
36
36
  },
37
- }));
37
+ });
38
38
  const AssemblySelector = (0, mobx_react_1.observer)(({ session, onChange, selected, InputProps, extra = 0, }) => {
39
39
  const { classes } = useStyles();
40
40
  const { assemblyNames, assemblyManager } = session;
41
41
  // constructs a localstorage key based on host/path/config to help
42
42
  // remember. non-config assists usage with e.g. embedded apps
43
43
  const config = new URLSearchParams(window.location.search).get('config');
44
- const [lastSelected, setLastSelected] = (0, util_1.useLocalStorage)(`lastAssembly-${[
45
- window.location.host + window.location.pathname,
46
- config,
47
- extra,
48
- ].join('-')}`, selected);
44
+ const [lastSelected, setLastSelected] = typeof jest === 'undefined'
45
+ ? (0, util_1.useLocalStorage)(`lastAssembly-${[
46
+ window.location.host + window.location.pathname,
47
+ config,
48
+ extra,
49
+ ].join('-')}`, selected)
50
+ : (0, react_1.useState)(selected);
49
51
  const selection = assemblyNames.includes(lastSelected || '')
50
52
  ? lastSelected
51
53
  : selected;
@@ -55,7 +57,7 @@ const AssemblySelector = (0, mobx_react_1.observer)(({ session, onChange, select
55
57
  }
56
58
  }, [selection, onChange, selected]);
57
59
  const error = assemblyNames.length ? '' : 'No configured assemblies';
58
- return (react_1.default.createElement(material_1.TextField, { select: true, label: "Assembly", variant: "outlined", helperText: error || 'Select assembly to view', value: selection, inputProps: { 'data-testid': 'assembly-selector' }, onChange: event => setLastSelected(event.target.value), error: !!error, InputProps: InputProps, disabled: !!error, className: classes.importFormEntry }, assemblyNames.map(name => {
60
+ return (react_1.default.createElement(material_1.TextField, { select: true, label: "Assembly", variant: "outlined", helperText: error || 'Select assembly to view', value: selection || '', inputProps: { 'data-testid': 'assembly-selector' }, onChange: event => setLastSelected(event.target.value), error: !!error, InputProps: InputProps, disabled: !!error, className: classes.importFormEntry }, assemblyNames.map(name => {
59
61
  const assembly = assemblyManager.get(name);
60
62
  const displayName = assembly ? (0, configuration_1.getConf)(assembly, 'displayName') : '';
61
63
  return (react_1.default.createElement(material_1.MenuItem, { key: name, value: name }, displayName || name));
package/ui/Dialog.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ /// <reference types="react" />
2
+ import { DialogProps } from '@mui/material';
3
+ declare function JBrowseDialog(props: DialogProps & {
4
+ title: string;
5
+ }): JSX.Element;
6
+ declare const _default: typeof JBrowseDialog;
7
+ export default _default;
package/ui/Dialog.js ADDED
@@ -0,0 +1,35 @@
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 material_1 = require("@mui/material");
8
+ const mobx_react_1 = require("mobx-react");
9
+ const mui_1 = require("tss-react/mui");
10
+ // icons
11
+ const Close_1 = __importDefault(require("@mui/icons-material/Close"));
12
+ const useStyles = (0, mui_1.makeStyles)()(theme => ({
13
+ closeButton: {
14
+ position: 'absolute',
15
+ right: theme.spacing(1),
16
+ top: theme.spacing(1),
17
+ color: theme.palette.grey[500],
18
+ },
19
+ }));
20
+ function JBrowseDialog(props) {
21
+ const { classes } = useStyles();
22
+ const { title, children, onClose } = props;
23
+ return (react_1.default.createElement(material_1.Dialog, { ...props },
24
+ react_1.default.createElement(material_1.ScopedCssBaseline, null,
25
+ react_1.default.createElement(material_1.DialogTitle, null,
26
+ title,
27
+ onClose ? (react_1.default.createElement(material_1.IconButton, { className: classes.closeButton, onClick: () => {
28
+ // @ts-ignore
29
+ onClose();
30
+ } },
31
+ react_1.default.createElement(Close_1.default, null))) : null),
32
+ react_1.default.createElement(material_1.Divider, null),
33
+ children)));
34
+ }
35
+ exports.default = (0, mobx_react_1.observer)(JBrowseDialog);
@@ -1,12 +1,12 @@
1
1
  import React from 'react';
2
2
  import { TypographyProps } from '@mui/material';
3
- declare type Variant = TypographyProps['variant'];
4
- declare type EditableTypographyClassKey = 'input' | 'inputBase' | 'inputRoot' | 'inputFocused';
5
- interface EditableTypographyPropTypes {
3
+ type Variant = TypographyProps['variant'];
4
+ type EditableTypographyClassKey = 'input' | 'inputBase' | 'inputRoot' | 'inputFocused';
5
+ interface Props {
6
6
  value: string;
7
7
  setValue: (value: string) => void;
8
8
  variant: Variant;
9
9
  classes?: Partial<Record<EditableTypographyClassKey, string>>;
10
10
  }
11
- declare const EditableTypography: React.ForwardRefExoticComponent<EditableTypographyPropTypes & React.RefAttributes<HTMLDivElement>>;
11
+ declare const EditableTypography: React.ForwardRefExoticComponent<Props & React.RefAttributes<HTMLDivElement>>;
12
12
  export default EditableTypography;
@@ -48,13 +48,12 @@ const useStyles = (0, mui_1.makeStyles)()(theme => ({
48
48
  const EditableTypography = react_1.default.forwardRef((props, ref) => {
49
49
  const { value, setValue, variant, ...other } = props;
50
50
  const [editedValue, setEditedValue] = (0, react_1.useState)();
51
- const [width, setWidth] = (0, react_1.useState)(0);
52
51
  const [sizerNode, setSizerNode] = (0, react_1.useState)(null);
53
52
  const [inputNode, setInputNode] = (0, react_1.useState)(null);
54
53
  const [blur, setBlur] = (0, react_1.useState)(false);
55
54
  (0, react_1.useEffect)(() => {
56
55
  if (blur) {
57
- inputNode && inputNode.blur();
56
+ inputNode === null || inputNode === void 0 ? void 0 : inputNode.blur();
58
57
  setBlur(false);
59
58
  }
60
59
  }, [blur, inputNode]);
@@ -64,12 +63,11 @@ const EditableTypography = react_1.default.forwardRef((props, ref) => {
64
63
  const { classes } = useStyles(props, { props });
65
64
  const theme = (0, material_1.useTheme)();
66
65
  const clientWidth = sizerNode === null || sizerNode === void 0 ? void 0 : sizerNode.clientWidth;
67
- if (clientWidth && clientWidth !== width) {
68
- setWidth(clientWidth);
69
- }
66
+ const width = clientWidth || 0;
67
+ const val = editedValue === undefined ? value : editedValue;
70
68
  return (react_1.default.createElement("div", { ...other, ref: ref },
71
69
  react_1.default.createElement("div", { style: { position: 'relative' } },
72
- react_1.default.createElement(material_1.Typography, { ref: (node) => setSizerNode(node), component: "span", variant: variant, className: classes.typography }, editedValue === undefined ? value : editedValue)),
70
+ react_1.default.createElement(material_1.Typography, { ref: (node) => setSizerNode(node), component: "span", variant: variant, className: classes.typography }, val)),
73
71
  react_1.default.createElement(material_1.InputBase, { inputRef: node => setInputNode(node), className: classes.inputBase, inputProps: {
74
72
  style: {
75
73
  width,
@@ -81,18 +79,16 @@ const EditableTypography = react_1.default.forwardRef((props, ref) => {
81
79
  input: classes.input,
82
80
  root: classes.inputRoot,
83
81
  focused: classes.inputFocused,
84
- }, value: editedValue === undefined ? value : editedValue, onChange: event => setEditedValue(event.target.value), onKeyDown: event => {
82
+ }, value: val, onChange: event => setEditedValue(event.target.value), onKeyDown: event => {
85
83
  if (event.key === 'Enter') {
86
- inputNode && inputNode.blur();
84
+ inputNode === null || inputNode === void 0 ? void 0 : inputNode.blur();
87
85
  }
88
86
  else if (event.key === 'Escape') {
89
87
  setEditedValue(undefined);
90
88
  setBlur(true);
91
89
  }
92
90
  }, onBlur: () => {
93
- if (editedValue && editedValue !== value) {
94
- setValue(editedValue);
95
- }
91
+ setValue(editedValue || '');
96
92
  setEditedValue(undefined);
97
93
  } })));
98
94
  });
@@ -3,13 +3,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- const Button_1 = __importDefault(require("@mui/material/Button"));
7
- const Dialog_1 = __importDefault(require("@mui/material/Dialog"));
8
- const DialogTitle_1 = __importDefault(require("@mui/material/DialogTitle"));
9
- const DialogContent_1 = __importDefault(require("@mui/material/DialogContent"));
10
- const DialogContentText_1 = __importDefault(require("@mui/material/DialogContentText"));
11
- const DialogActions_1 = __importDefault(require("@mui/material/DialogActions"));
12
6
  const react_1 = __importDefault(require("react"));
7
+ const material_1 = require("@mui/material");
8
+ const Dialog_1 = __importDefault(require("@jbrowse/core/ui/Dialog"));
13
9
  exports.default = ({ onClose, open, onFactoryReset, }) => {
14
10
  function handleDialogClose(action) {
15
11
  if (action === 'reset') {
@@ -17,11 +13,10 @@ exports.default = ({ onClose, open, onFactoryReset, }) => {
17
13
  }
18
14
  onClose();
19
15
  }
20
- return (react_1.default.createElement(Dialog_1.default, { open: open, onClose: () => handleDialogClose() },
21
- react_1.default.createElement(DialogTitle_1.default, { id: "alert-dialog-title" }, "Reset"),
22
- react_1.default.createElement(DialogContent_1.default, null,
23
- react_1.default.createElement(DialogContentText_1.default, { id: "alert-dialog-description" }, "Are you sure you want to reset? This will restore the default configuration.")),
24
- react_1.default.createElement(DialogActions_1.default, null,
25
- react_1.default.createElement(Button_1.default, { onClick: () => handleDialogClose(), color: "primary" }, "Cancel"),
26
- react_1.default.createElement(Button_1.default, { onClick: () => handleDialogClose('reset'), color: "primary", variant: "contained" }, "OK"))));
16
+ return (react_1.default.createElement(Dialog_1.default, { title: "Reset", onClose: () => handleDialogClose(), open: open },
17
+ react_1.default.createElement(material_1.DialogContent, null,
18
+ react_1.default.createElement(material_1.DialogContentText, null, "Are you sure you want to reset? This will restore the default configuration.")),
19
+ react_1.default.createElement(material_1.DialogActions, null,
20
+ react_1.default.createElement(material_1.Button, { onClick: () => handleDialogClose(), color: "primary" }, "Cancel"),
21
+ react_1.default.createElement(material_1.Button, { onClick: () => handleDialogClose('reset'), color: "primary", variant: "contained" }, "OK"))));
27
22
  };
package/ui/Logo.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /// <reference types="react" />
2
- declare type LogoVariant = 'color' | 'black' | 'white';
2
+ type LogoVariant = 'color' | 'black' | 'white';
3
3
  interface LogoProps {
4
4
  variant?: LogoVariant;
5
5
  }
package/ui/Menu.d.ts CHANGED
@@ -8,7 +8,7 @@ interface MenuItemEndDecorationSelectorProps {
8
8
  checked: boolean;
9
9
  disabled?: boolean;
10
10
  }
11
- declare type MenuItemEndDecorationProps = MenuItemEndDecorationSubMenuProps | MenuItemEndDecorationSelectorProps;
11
+ type MenuItemEndDecorationProps = MenuItemEndDecorationSubMenuProps | MenuItemEndDecorationSelectorProps;
12
12
  export declare function MenuItemEndDecoration(props: MenuItemEndDecorationProps): JSX.Element;
13
13
  export interface MenuDivider {
14
14
  priority?: number;
@@ -44,7 +44,7 @@ export interface SubMenuItem extends BaseMenuItem {
44
44
  type?: 'subMenu';
45
45
  subMenu: MenuItem[];
46
46
  }
47
- export declare type MenuItem = MenuDivider | MenuSubHeader | NormalMenuItem | CheckboxMenuItem | RadioMenuItem | SubMenuItem;
47
+ export type MenuItem = MenuDivider | MenuSubHeader | NormalMenuItem | CheckboxMenuItem | RadioMenuItem | SubMenuItem;
48
48
  interface MenuProps extends PopoverProps {
49
49
  menuItems: MenuItem[];
50
50
  onMenuItemClick: (event: React.MouseEvent<HTMLLIElement, MouseEvent>, callback: Function) => void;
@@ -6,24 +6,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const react_1 = __importDefault(require("react"));
7
7
  const mobx_react_1 = require("mobx-react");
8
8
  const material_1 = require("@mui/material");
9
- const mui_1 = require("tss-react/mui");
10
- const Close_1 = __importDefault(require("@mui/icons-material/Close"));
11
- const useStyles = (0, mui_1.makeStyles)()(theme => ({
12
- closeButton: {
13
- position: 'absolute',
14
- right: theme.spacing(1),
15
- top: theme.spacing(1),
16
- color: theme.palette.grey[500],
17
- },
18
- }));
9
+ const Dialog_1 = __importDefault(require("./Dialog"));
19
10
  function ReturnToImportFormDialog({ model, handleClose, }) {
20
- const { classes } = useStyles();
21
- return (react_1.default.createElement(material_1.Dialog, { maxWidth: "xl", open: true, onClose: handleClose },
22
- react_1.default.createElement(material_1.DialogTitle, null,
23
- "Reference sequence",
24
- handleClose ? (react_1.default.createElement(material_1.IconButton, { className: classes.closeButton, onClick: () => handleClose(), size: "large" },
25
- react_1.default.createElement(Close_1.default, null))) : null),
26
- react_1.default.createElement(material_1.Divider, null),
11
+ return (react_1.default.createElement(Dialog_1.default, { maxWidth: "xl", open: true, onClose: handleClose, title: "Reference sequence" },
27
12
  react_1.default.createElement(material_1.DialogContent, null,
28
13
  react_1.default.createElement(material_1.Typography, null, "Are you sure you want to return to the import form? This will lose your current view")),
29
14
  react_1.default.createElement(material_1.DialogActions, null,
package/ui/Snackbar.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /// <reference types="react" />
2
2
  import { IAnyStateTreeNode } from 'mobx-state-tree';
3
3
  import { AbstractSessionModel, NotificationLevel, SnackAction } from '../util';
4
- declare type SnackbarMessage = [string, NotificationLevel, SnackAction];
4
+ type SnackbarMessage = [string, NotificationLevel, SnackAction];
5
5
  interface SnackbarSession extends AbstractSessionModel {
6
6
  snackbarMessages: SnackbarMessage[];
7
7
  popSnackbarMessage: () => unknown;
@@ -1,8 +1,9 @@
1
1
  import React from 'react';
2
2
  import { IBaseViewModel } from '../pluggableElementTypes/models';
3
- declare const ViewContainer: ({ view, onClose, style, children, }: {
3
+ declare const ViewContainer: ({ view, onClose, onMinimize, style, children, }: {
4
4
  view: IBaseViewModel;
5
5
  onClose: () => void;
6
+ onMinimize: () => void;
6
7
  style?: React.CSSProperties | undefined;
7
8
  children: React.ReactNode;
8
9
  }) => JSX.Element;
@@ -29,13 +29,18 @@ Object.defineProperty(exports, "__esModule", { value: true });
29
29
  const react_1 = __importStar(require("react"));
30
30
  const material_1 = require("@mui/material");
31
31
  const mui_1 = require("tss-react/mui");
32
- const styles_1 = require("@mui/material/styles");
33
32
  const mobx_react_1 = require("mobx-react");
34
33
  const mobx_state_tree_1 = require("mobx-state-tree");
35
34
  const react_use_measure_1 = __importDefault(require("react-use-measure"));
36
35
  // icons
37
36
  const Close_1 = __importDefault(require("@mui/icons-material/Close"));
37
+ const Minimize_1 = __importDefault(require("@mui/icons-material/Minimize"));
38
+ const Add_1 = __importDefault(require("@mui/icons-material/Add"));
38
39
  const Menu_1 = __importDefault(require("@mui/icons-material/Menu"));
40
+ const ArrowDownward_1 = __importDefault(require("@mui/icons-material/ArrowDownward"));
41
+ const ArrowUpward_1 = __importDefault(require("@mui/icons-material/ArrowUpward"));
42
+ // locals
43
+ const util_1 = require("../util");
39
44
  const EditableTypography_1 = __importDefault(require("./EditableTypography"));
40
45
  const Menu_2 = __importDefault(require("./Menu"));
41
46
  const useStyles = (0, mui_1.makeStyles)()(theme => ({
@@ -50,14 +55,6 @@ const useStyles = (0, mui_1.makeStyles)()(theme => ({
50
55
  grow: {
51
56
  flexGrow: 1,
52
57
  },
53
- iconRoot: {
54
- '&:hover': {
55
- backgroundColor: (0, styles_1.alpha)(theme.palette.secondary.contrastText, theme.palette.action.hoverOpacity),
56
- '@media (hover: none)': {
57
- backgroundColor: 'transparent',
58
- },
59
- },
60
- },
61
58
  input: {
62
59
  paddingBottom: 0,
63
60
  paddingTop: 2,
@@ -78,17 +75,34 @@ const useStyles = (0, mui_1.makeStyles)()(theme => ({
78
75
  const ViewMenu = (0, mobx_react_1.observer)(({ model, IconButtonProps, IconProps, }) => {
79
76
  const [anchorEl, setAnchorEl] = (0, react_1.useState)();
80
77
  const { menuItems } = model;
81
- // <=1.3.3 didn't use a function
82
- const items = typeof menuItems === 'function' ? menuItems() : menuItems;
83
- return (items === null || items === void 0 ? void 0 : items.length) ? (react_1.default.createElement(react_1.default.Fragment, null,
84
- react_1.default.createElement(material_1.IconButton, { ...IconButtonProps, style: { padding: 3 }, onClick: event => setAnchorEl(event.currentTarget), "data-testid": "view_menu_icon", size: "small" },
78
+ const session = (0, util_1.getSession)(model);
79
+ const items = [
80
+ ...(session.views.length > 1
81
+ ? [
82
+ {
83
+ label: 'Move view up',
84
+ icon: ArrowUpward_1.default,
85
+ onClick: () => session.moveViewUp(model.id),
86
+ },
87
+ {
88
+ label: 'Move view down',
89
+ icon: ArrowDownward_1.default,
90
+ onClick: () => session.moveViewDown(model.id),
91
+ },
92
+ ]
93
+ : []),
94
+ // <=1.3.3 didn't use a function, so check as value also
95
+ ...((typeof menuItems === 'function' ? menuItems() : menuItems) || []),
96
+ ];
97
+ return (react_1.default.createElement(react_1.default.Fragment, null,
98
+ react_1.default.createElement(material_1.IconButton, { ...IconButtonProps, onClick: event => setAnchorEl(event.currentTarget), "data-testid": "view_menu_icon" },
85
99
  react_1.default.createElement(Menu_1.default, { ...IconProps, fontSize: "small" })),
86
100
  react_1.default.createElement(Menu_2.default, { anchorEl: anchorEl, open: Boolean(anchorEl), onMenuItemClick: (_event, callback) => {
87
101
  callback();
88
102
  setAnchorEl(undefined);
89
- }, onClose: () => setAnchorEl(undefined), menuItems: model.menuItems() }))) : null;
103
+ }, onClose: () => setAnchorEl(undefined), menuItems: items })));
90
104
  });
91
- const ViewContainer = (0, mobx_react_1.observer)(({ view, onClose, style, children, }) => {
105
+ const ViewContainer = (0, mobx_react_1.observer)(({ view, onClose, onMinimize, style, children, }) => {
92
106
  var _a;
93
107
  const { classes } = useStyles();
94
108
  const theme = (0, material_1.useTheme)();
@@ -109,24 +123,22 @@ const ViewContainer = (0, mobx_react_1.observer)(({ view, onClose, style, childr
109
123
  }, []);
110
124
  return (react_1.default.createElement(material_1.Paper, { ref: ref, elevation: 12, className: classes.viewContainer, style: { ...style, padding: `0px ${padWidth} ${padWidth}` } },
111
125
  react_1.default.createElement("div", { ref: scrollRef, style: { display: 'flex' } },
112
- react_1.default.createElement(ViewMenu, { model: view, IconButtonProps: {
113
- classes: { root: classes.iconRoot },
114
- edge: 'start',
115
- }, IconProps: { className: classes.icon } }),
126
+ react_1.default.createElement(ViewMenu, { model: view, IconProps: { className: classes.icon } }),
116
127
  react_1.default.createElement("div", { className: classes.grow }),
117
128
  react_1.default.createElement(material_1.Tooltip, { title: "Rename view", arrow: true },
118
- react_1.default.createElement(EditableTypography_1.default, { value: view.displayName ||
129
+ react_1.default.createElement(EditableTypography_1.default, { value: (view.displayName ||
119
130
  (
120
131
  // @ts-ignore
121
132
  (_a = view.assemblyNames) === null || _a === void 0 ? void 0 : _a.join(',')) ||
122
- 'Untitled view', setValue: val => view.setDisplayName(val), variant: "body2", classes: {
133
+ 'Untitled view') + (view.minimized ? ' (minimized)' : ''), setValue: val => view.setDisplayName(val), variant: "body2", classes: {
123
134
  input: classes.input,
124
135
  inputBase: classes.inputBase,
125
136
  inputRoot: classes.inputRoot,
126
137
  inputFocused: classes.inputFocused,
127
138
  } })),
128
139
  react_1.default.createElement("div", { className: classes.grow }),
129
- react_1.default.createElement(material_1.IconButton, { "data-testid": "close_view", classes: { root: classes.iconRoot }, edge: "end", size: "small", onClick: onClose },
140
+ react_1.default.createElement(material_1.IconButton, { "data-testid": "minimize_view", onClick: onMinimize }, view.minimized ? (react_1.default.createElement(Add_1.default, { className: classes.icon, fontSize: "small" })) : (react_1.default.createElement(Minimize_1.default, { className: classes.icon, fontSize: "small" }))),
141
+ react_1.default.createElement(material_1.IconButton, { "data-testid": "close_view", onClick: onClose },
130
142
  react_1.default.createElement(Close_1.default, { className: classes.icon, fontSize: "small" }))),
131
143
  react_1.default.createElement(material_1.Paper, null, children)));
132
144
  });
package/ui/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from './theme';
2
2
  export { LogoFull, Logomark } from './Logo';
3
+ export { default as Dialog } from './Dialog';
3
4
  export { default as App } from './App';
4
5
  export { default as ReturnToImportFormDialog } from './ReturnToImportFormDialog';
5
6
  export { default as ErrorMessage } from './ErrorMessage';
package/ui/index.js CHANGED
@@ -17,11 +17,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
17
17
  return (mod && mod.__esModule) ? mod : { "default": mod };
18
18
  };
19
19
  Object.defineProperty(exports, "__esModule", { value: true });
20
- exports.LoadingEllipses = exports.SanitizedHTML = exports.CascadingMenu = exports.Menu = exports.FatalErrorDialog = exports.Tooltip = exports.FactoryResetDialog = exports.EditableTypography = exports.ResizeHandle = exports.PrerenderedCanvas = exports.FileSelector = exports.AssemblySelector = exports.ErrorMessage = exports.ReturnToImportFormDialog = exports.App = exports.Logomark = exports.LogoFull = void 0;
20
+ exports.LoadingEllipses = exports.SanitizedHTML = exports.CascadingMenu = exports.Menu = exports.FatalErrorDialog = exports.Tooltip = exports.FactoryResetDialog = exports.EditableTypography = exports.ResizeHandle = exports.PrerenderedCanvas = exports.FileSelector = exports.AssemblySelector = exports.ErrorMessage = exports.ReturnToImportFormDialog = exports.App = exports.Dialog = exports.Logomark = exports.LogoFull = void 0;
21
21
  __exportStar(require("./theme"), exports);
22
22
  var Logo_1 = require("./Logo");
23
23
  Object.defineProperty(exports, "LogoFull", { enumerable: true, get: function () { return Logo_1.LogoFull; } });
24
24
  Object.defineProperty(exports, "Logomark", { enumerable: true, get: function () { return Logo_1.Logomark; } });
25
+ var Dialog_1 = require("./Dialog");
26
+ Object.defineProperty(exports, "Dialog", { enumerable: true, get: function () { return __importDefault(Dialog_1).default; } });
25
27
  var App_1 = require("./App");
26
28
  Object.defineProperty(exports, "App", { enumerable: true, get: function () { return __importDefault(App_1).default; } });
27
29
  var ReturnToImportFormDialog_1 = require("./ReturnToImportFormDialog");