@jbrowse/plugin-linear-genome-view 3.0.5 → 3.1.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 (63) hide show
  1. package/dist/BaseLinearDisplay/components/BlockErrorMessage.d.ts +7 -0
  2. package/dist/BaseLinearDisplay/components/{BlockError.js → BlockErrorMessage.js} +6 -3
  3. package/dist/BaseLinearDisplay/components/BlockLoadingMessage.d.ts +6 -0
  4. package/dist/BaseLinearDisplay/components/BlockLoadingMessage.js +26 -0
  5. package/dist/BaseLinearDisplay/components/BlockMsg.js +4 -2
  6. package/dist/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js +4 -24
  7. package/dist/LinearGenomeView/components/CenterLine.js +1 -1
  8. package/dist/LinearGenomeView/components/Gridlines.d.ts +2 -1
  9. package/dist/LinearGenomeView/components/Gridlines.js +3 -4
  10. package/dist/LinearGenomeView/components/Header.js +2 -0
  11. package/dist/LinearGenomeView/components/LinearGenomeView.js +2 -49
  12. package/dist/LinearGenomeView/components/LinearGenomeViewContainer.d.ts +5 -0
  13. package/dist/LinearGenomeView/components/LinearGenomeViewContainer.js +98 -0
  14. package/dist/LinearGenomeView/components/MiniControls.js +0 -1
  15. package/dist/LinearGenomeView/components/NoTracksActiveButton.js +1 -1
  16. package/dist/LinearGenomeView/components/OverviewRubberband.js +0 -1
  17. package/dist/LinearGenomeView/components/Rubberband.js +25 -2
  18. package/dist/LinearGenomeView/components/RubberbandSpan.d.ts +3 -1
  19. package/dist/LinearGenomeView/components/RubberbandSpan.js +8 -6
  20. package/dist/LinearGenomeView/components/Scalebar.js +2 -2
  21. package/dist/LinearGenomeView/components/TrackContainer.js +9 -4
  22. package/dist/LinearGenomeView/components/TrackLabel.js +1 -1
  23. package/dist/LinearGenomeView/components/TrackLabelContainer.js +1 -1
  24. package/dist/LinearGenomeView/components/TrackLabelMenu.js +21 -0
  25. package/dist/LinearGenomeView/components/TrackRenderingContainer.js +0 -1
  26. package/dist/LinearGenomeView/components/TracksContainer.js +3 -4
  27. package/dist/LinearGenomeView/components/VerticalGuide.js +30 -5
  28. package/dist/LinearGenomeView/model.d.ts +4 -0
  29. package/dist/LinearGenomeView/model.js +27 -0
  30. package/dist/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +2 -2
  31. package/esm/BaseLinearDisplay/components/BlockErrorMessage.d.ts +7 -0
  32. package/esm/BaseLinearDisplay/components/{BlockError.js → BlockErrorMessage.js} +6 -3
  33. package/esm/BaseLinearDisplay/components/BlockLoadingMessage.d.ts +6 -0
  34. package/esm/BaseLinearDisplay/components/BlockLoadingMessage.js +24 -0
  35. package/esm/BaseLinearDisplay/components/BlockMsg.js +4 -2
  36. package/esm/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js +4 -24
  37. package/esm/LinearGenomeView/components/CenterLine.js +1 -1
  38. package/esm/LinearGenomeView/components/Gridlines.d.ts +2 -1
  39. package/esm/LinearGenomeView/components/Gridlines.js +3 -4
  40. package/esm/LinearGenomeView/components/Header.js +2 -0
  41. package/esm/LinearGenomeView/components/LinearGenomeView.js +3 -50
  42. package/esm/LinearGenomeView/components/LinearGenomeViewContainer.d.ts +5 -0
  43. package/esm/LinearGenomeView/components/LinearGenomeViewContainer.js +60 -0
  44. package/esm/LinearGenomeView/components/MiniControls.js +0 -1
  45. package/esm/LinearGenomeView/components/NoTracksActiveButton.js +1 -1
  46. package/esm/LinearGenomeView/components/OverviewRubberband.js +0 -1
  47. package/esm/LinearGenomeView/components/Rubberband.js +26 -3
  48. package/esm/LinearGenomeView/components/RubberbandSpan.d.ts +3 -1
  49. package/esm/LinearGenomeView/components/RubberbandSpan.js +8 -6
  50. package/esm/LinearGenomeView/components/Scalebar.js +2 -2
  51. package/esm/LinearGenomeView/components/TrackContainer.js +9 -4
  52. package/esm/LinearGenomeView/components/TrackLabel.js +1 -1
  53. package/esm/LinearGenomeView/components/TrackLabelContainer.js +1 -1
  54. package/esm/LinearGenomeView/components/TrackLabelMenu.js +21 -0
  55. package/esm/LinearGenomeView/components/TrackRenderingContainer.js +0 -1
  56. package/esm/LinearGenomeView/components/TracksContainer.js +3 -4
  57. package/esm/LinearGenomeView/components/VerticalGuide.js +32 -7
  58. package/esm/LinearGenomeView/model.d.ts +4 -0
  59. package/esm/LinearGenomeView/model.js +27 -0
  60. package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +2 -2
  61. package/package.json +3 -3
  62. package/dist/BaseLinearDisplay/components/BlockError.d.ts +0 -4
  63. package/esm/BaseLinearDisplay/components/BlockError.d.ts +0 -4
@@ -0,0 +1,7 @@
1
+ declare const BlockErrorMessage: ({ model, }: {
2
+ model: {
3
+ error?: unknown;
4
+ reload: () => void;
5
+ };
6
+ }) => import("react/jsx-runtime").JSX.Element;
7
+ export default BlockErrorMessage;
@@ -11,14 +11,17 @@ const Report_1 = __importDefault(require("@mui/icons-material/Report"));
11
11
  const material_1 = require("@mui/material");
12
12
  const mobx_react_1 = require("mobx-react");
13
13
  const BlockMsg_1 = __importDefault(require("./BlockMsg"));
14
- const BlockError = (0, mobx_react_1.observer)(function ({ model }) {
14
+ const BlockErrorMessage = (0, mobx_react_1.observer)(function ({ model, }) {
15
15
  return ((0, jsx_runtime_1.jsx)(BlockMsg_1.default, { message: `${model.error}`, severity: "error", action: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(material_1.Tooltip, { title: "Reload track", children: (0, jsx_runtime_1.jsx)(material_1.IconButton, { "data-testid": "reload_button", onClick: () => {
16
16
  model.reload();
17
17
  }, children: (0, jsx_runtime_1.jsx)(Refresh_1.default, {}) }) }), (0, jsx_runtime_1.jsx)(material_1.Tooltip, { title: "Show stack trace", children: (0, jsx_runtime_1.jsx)(material_1.IconButton, { onClick: () => {
18
18
  (0, util_1.getSession)(model).queueDialog(onClose => [
19
19
  ErrorMessageStackTraceDialog_1.default,
20
- { onClose, error: model.error },
20
+ {
21
+ onClose,
22
+ error: model.error,
23
+ },
21
24
  ]);
22
25
  }, children: (0, jsx_runtime_1.jsx)(Report_1.default, {}) }) })] }) }));
23
26
  });
24
- exports.default = BlockError;
27
+ exports.default = BlockErrorMessage;
@@ -0,0 +1,6 @@
1
+ declare const BlockLoadingMessage: ({ model, }: {
2
+ model: {
3
+ status?: string;
4
+ };
5
+ }) => import("react/jsx-runtime").JSX.Element;
6
+ export default BlockLoadingMessage;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const jsx_runtime_1 = require("react/jsx-runtime");
4
+ const ui_1 = require("@jbrowse/core/ui");
5
+ const mobx_react_1 = require("mobx-react");
6
+ const mobx_state_tree_1 = require("mobx-state-tree");
7
+ const mui_1 = require("tss-react/mui");
8
+ const useStyles = (0, mui_1.makeStyles)()(theme => {
9
+ const bg = theme.palette.action.disabledBackground;
10
+ return {
11
+ loading: {
12
+ paddingLeft: '0.6em',
13
+ backgroundColor: theme.palette.background.default,
14
+ backgroundImage: `repeating-linear-gradient(45deg, transparent, transparent 5px, ${bg} 5px, ${bg} 10px)`,
15
+ textAlign: 'center',
16
+ },
17
+ };
18
+ });
19
+ const BlockLoadingMessage = (0, mobx_react_1.observer)(function ({ model, }) {
20
+ const { classes } = useStyles();
21
+ const { status: blockStatus } = model;
22
+ const { message: displayStatus } = (0, mobx_state_tree_1.getParent)(model, 2);
23
+ const status = displayStatus || blockStatus;
24
+ return ((0, jsx_runtime_1.jsx)("div", { className: classes.loading, children: (0, jsx_runtime_1.jsx)(ui_1.LoadingEllipses, { message: status }) }));
25
+ });
26
+ exports.default = BlockLoadingMessage;
@@ -12,7 +12,9 @@ const useStyles = (0, mui_1.makeStyles)()({
12
12
  });
13
13
  function BlockMsg({ message, severity, action, }) {
14
14
  const { classes } = useStyles();
15
- return ((0, jsx_runtime_1.jsx)(material_1.Alert, { onClick: event => {
15
+ return ((0, jsx_runtime_1.jsx)(material_1.Alert, { severity: severity, action: action, classes: {
16
+ message: classes.ellipses,
17
+ }, onMouseDown: event => {
16
18
  event.stopPropagation();
17
- }, severity: severity, action: action, classes: { message: classes.ellipses }, children: (0, jsx_runtime_1.jsx)(material_1.Tooltip, { title: message, children: (0, jsx_runtime_1.jsx)("div", { children: message }) }) }));
19
+ }, children: (0, jsx_runtime_1.jsx)(material_1.Tooltip, { title: message, children: (0, jsx_runtime_1.jsx)("div", { children: message }) }) }));
18
20
  }
@@ -38,39 +38,19 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  const jsx_runtime_1 = require("react/jsx-runtime");
40
40
  const react_1 = require("react");
41
- const ui_1 = require("@jbrowse/core/ui");
42
41
  const mobx_react_1 = require("mobx-react");
43
- const mobx_state_tree_1 = require("mobx-state-tree");
44
- const mui_1 = require("tss-react/mui");
42
+ const BlockLoadingMessage_1 = __importDefault(require("./BlockLoadingMessage"));
45
43
  const BlockMsg_1 = __importDefault(require("./BlockMsg"));
46
- const BlockError = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./BlockError'))));
47
- const useStyles = (0, mui_1.makeStyles)()(theme => {
48
- const bg = theme.palette.action.disabledBackground;
49
- return {
50
- loading: {
51
- paddingLeft: '0.6em',
52
- backgroundColor: theme.palette.background.default,
53
- backgroundImage: `repeating-linear-gradient(45deg, transparent, transparent 5px, ${bg} 5px, ${bg} 10px)`,
54
- textAlign: 'center',
55
- },
56
- };
57
- });
58
- const LoadingMessage = (0, mobx_react_1.observer)(({ model }) => {
59
- const { classes } = useStyles();
60
- const { status: blockStatus } = model;
61
- const { message: displayStatus } = (0, mobx_state_tree_1.getParent)(model, 2);
62
- const status = displayStatus || blockStatus;
63
- return ((0, jsx_runtime_1.jsx)("div", { className: classes.loading, children: (0, jsx_runtime_1.jsx)(ui_1.LoadingEllipses, { message: status }) }));
64
- });
44
+ const BlockErrorMessage = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./BlockErrorMessage'))));
65
45
  const ServerSideRenderedBlockContent = (0, mobx_react_1.observer)(function ({ model, }) {
66
46
  if (model.error) {
67
- return ((0, jsx_runtime_1.jsx)(react_1.Suspense, { fallback: null, children: (0, jsx_runtime_1.jsx)(BlockError, { model: model }) }));
47
+ return ((0, jsx_runtime_1.jsx)(react_1.Suspense, { fallback: null, children: (0, jsx_runtime_1.jsx)(BlockErrorMessage, { model: model }) }));
68
48
  }
69
49
  else if (model.message) {
70
50
  return (0, react_1.isValidElement)(model.message) ? (model.message) : ((0, jsx_runtime_1.jsx)(BlockMsg_1.default, { message: `${model.message}`, severity: "info" }));
71
51
  }
72
52
  else if (!model.filled) {
73
- return (0, jsx_runtime_1.jsx)(LoadingMessage, { model: model });
53
+ return (0, jsx_runtime_1.jsx)(BlockLoadingMessage_1.default, { model: model });
74
54
  }
75
55
  else {
76
56
  return model.reactElement;
@@ -8,7 +8,7 @@ const useStyles = (0, mui_1.makeStyles)()(theme => ({
8
8
  centerLineContainer: {
9
9
  background: 'transparent',
10
10
  height: '100%',
11
- zIndex: 5,
11
+ zIndex: 4,
12
12
  position: 'absolute',
13
13
  border: `1px ${theme.palette.action.active} dashed`,
14
14
  borderTop: 'none',
@@ -1,6 +1,7 @@
1
1
  import type { LinearGenomeViewModel } from '..';
2
2
  type LGV = LinearGenomeViewModel;
3
- declare const Gridlines: ({ model }: {
3
+ declare const Gridlines: ({ model, offset, }: {
4
4
  model: LGV;
5
+ offset?: number;
5
6
  }) => import("react/jsx-runtime").JSX.Element;
6
7
  export default Gridlines;
@@ -8,15 +8,14 @@ const util_1 = require("../util");
8
8
  const useStyles = (0, mui_1.makeStyles)()(theme => ({
9
9
  verticalGuidesZoomContainer: {
10
10
  position: 'absolute',
11
+ top: 0,
11
12
  height: '100%',
12
13
  width: '100%',
13
- zIndex: 1,
14
14
  pointerEvents: 'none',
15
15
  },
16
16
  verticalGuidesContainer: {
17
17
  position: 'absolute',
18
18
  height: '100%',
19
- zIndex: 1,
20
19
  pointerEvents: 'none',
21
20
  display: 'flex',
22
21
  },
@@ -58,13 +57,13 @@ const RenderedVerticalGuides = (0, mobx_react_1.observer)(({ model }) => {
58
57
  return null;
59
58
  }) }));
60
59
  });
61
- const Gridlines = (0, mobx_react_1.observer)(function ({ model }) {
60
+ const Gridlines = (0, mobx_react_1.observer)(function ({ model, offset = 0, }) {
62
61
  const { classes } = useStyles();
63
62
  const offsetLeft = model.staticBlocks.offsetPx - model.offsetPx;
64
63
  return ((0, jsx_runtime_1.jsx)("div", { className: classes.verticalGuidesZoomContainer, style: {
65
64
  transform: model.scaleFactor !== 1 ? `scaleX(${model.scaleFactor})` : undefined,
66
65
  }, children: (0, jsx_runtime_1.jsx)("div", { className: classes.verticalGuidesContainer, style: {
67
- left: offsetLeft,
66
+ left: offsetLeft - offset,
68
67
  width: model.staticBlocks.totalWidthPx,
69
68
  }, children: (0, jsx_runtime_1.jsx)(RenderedVerticalGuides, { model: model }) }) }));
70
69
  });
@@ -13,9 +13,11 @@ const HeaderTrackSelectorButton_1 = __importDefault(require("./HeaderTrackSelect
13
13
  const HeaderZoomControls_1 = __importDefault(require("./HeaderZoomControls"));
14
14
  const OverviewScalebar_1 = __importDefault(require("./OverviewScalebar"));
15
15
  const SearchBox_1 = __importDefault(require("./SearchBox"));
16
+ const consts_1 = require("../consts");
16
17
  const useStyles = (0, mui_1.makeStyles)()({
17
18
  headerBar: {
18
19
  display: 'flex',
20
+ height: consts_1.HEADER_BAR_HEIGHT,
19
21
  },
20
22
  headerForm: {
21
23
  flexWrap: 'nowrap',
@@ -39,21 +39,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
39
39
  const jsx_runtime_1 = require("react/jsx-runtime");
40
40
  const react_1 = require("react");
41
41
  const ui_1 = require("@jbrowse/core/ui");
42
- const util_1 = require("@jbrowse/core/util");
43
42
  const mobx_react_1 = require("mobx-react");
44
- const mui_1 = require("tss-react/mui");
45
- const TrackContainer_1 = __importDefault(require("./TrackContainer"));
46
- const TracksContainer_1 = __importDefault(require("./TracksContainer"));
43
+ const LinearGenomeViewContainer_1 = __importDefault(require("./LinearGenomeViewContainer"));
47
44
  const ImportForm = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./ImportForm'))));
48
- const NoTracksActiveButton = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./NoTracksActiveButton'))));
49
- const useStyles = (0, mui_1.makeStyles)()({
50
- rel: {
51
- position: 'relative',
52
- },
53
- top: {
54
- zIndex: 1000,
55
- },
56
- });
57
45
  const LinearGenomeView = (0, mobx_react_1.observer)(function ({ model, }) {
58
46
  const { error, initialized, hasDisplayedRegions } = model;
59
47
  if (!initialized && !error) {
@@ -63,42 +51,7 @@ const LinearGenomeView = (0, mobx_react_1.observer)(function ({ model, }) {
63
51
  return (0, jsx_runtime_1.jsx)(ImportForm, { model: model });
64
52
  }
65
53
  else {
66
- return (0, jsx_runtime_1.jsx)(LinearGenomeViewContainer, { model: model });
54
+ return (0, jsx_runtime_1.jsx)(LinearGenomeViewContainer_1.default, { model: model });
67
55
  }
68
56
  });
69
- const LinearGenomeViewContainer = (0, mobx_react_1.observer)(function ({ model, }) {
70
- const { tracks } = model;
71
- const { classes } = useStyles();
72
- const session = (0, util_1.getSession)(model);
73
- const ref = (0, react_1.useRef)(null);
74
- const MiniControlsComponent = model.MiniControlsComponent();
75
- const HeaderComponent = model.HeaderComponent();
76
- (0, react_1.useEffect)(() => {
77
- function handleSelectView(e) {
78
- var _a, _b;
79
- if (e.target instanceof Element && ((_a = ref.current) === null || _a === void 0 ? void 0 : _a.contains(e.target))) {
80
- (_b = session.setFocusedViewId) === null || _b === void 0 ? void 0 : _b.call(session, model.id);
81
- }
82
- }
83
- document.addEventListener('mousedown', handleSelectView);
84
- document.addEventListener('keydown', handleSelectView);
85
- return () => {
86
- document.removeEventListener('mousedown', handleSelectView);
87
- document.removeEventListener('keydown', handleSelectView);
88
- };
89
- }, [session, model]);
90
- return ((0, jsx_runtime_1.jsxs)("div", { className: classes.rel, ref: ref, onMouseLeave: () => {
91
- session.setHovered(undefined);
92
- }, onMouseMove: event => {
93
- const c = ref.current;
94
- if (!c) {
95
- return;
96
- }
97
- const { tracks } = model;
98
- const leftPx = event.clientX - c.getBoundingClientRect().left;
99
- const hoverPosition = model.pxToBp(leftPx);
100
- const hoverFeature = tracks.find(t => t.displays[0].featureUnderMouse);
101
- session.setHovered({ hoverPosition, hoverFeature });
102
- }, children: [(0, jsx_runtime_1.jsx)(HeaderComponent, { model: model }), (0, jsx_runtime_1.jsx)(MiniControlsComponent, { model: model }), (0, jsx_runtime_1.jsx)(TracksContainer_1.default, { model: model, children: !tracks.length ? ((0, jsx_runtime_1.jsx)(react_1.Suspense, { fallback: null, children: (0, jsx_runtime_1.jsx)(NoTracksActiveButton, { model: model }) })) : (tracks.map(track => ((0, jsx_runtime_1.jsx)(TrackContainer_1.default, { model: model, track: track }, track.id)))) })] }));
103
- });
104
57
  exports.default = LinearGenomeView;
@@ -0,0 +1,5 @@
1
+ import type { LinearGenomeViewModel } from '..';
2
+ declare const LinearGenomeViewContainer: ({ model, }: {
3
+ model: LinearGenomeViewModel;
4
+ }) => import("react/jsx-runtime").JSX.Element;
5
+ export default LinearGenomeViewContainer;
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ const jsx_runtime_1 = require("react/jsx-runtime");
40
+ const react_1 = require("react");
41
+ const ui_1 = require("@jbrowse/core/ui");
42
+ const util_1 = require("@jbrowse/core/util");
43
+ const Paper_1 = __importDefault(require("@mui/material/Paper"));
44
+ const mobx_react_1 = require("mobx-react");
45
+ const mui_1 = require("tss-react/mui");
46
+ const TrackContainer_1 = __importDefault(require("./TrackContainer"));
47
+ const TracksContainer_1 = __importDefault(require("./TracksContainer"));
48
+ const NoTracksActiveButton = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./NoTracksActiveButton'))));
49
+ const useStyles = (0, mui_1.makeStyles)()(theme => ({
50
+ header: {
51
+ background: theme.palette.background.paper,
52
+ top: ui_1.VIEW_HEADER_HEIGHT,
53
+ zIndex: 850,
54
+ },
55
+ pinnedTracks: {
56
+ position: 'sticky',
57
+ zIndex: 3,
58
+ },
59
+ rel: {
60
+ position: 'relative',
61
+ },
62
+ }));
63
+ const LinearGenomeViewContainer = (0, mobx_react_1.observer)(function ({ model, }) {
64
+ const { pinnedTracks, stickyViewHeaders, pinnedTracksTop, tracks, unpinnedTracks, } = model;
65
+ const { classes } = useStyles();
66
+ const session = (0, util_1.getSession)(model);
67
+ const ref = (0, react_1.useRef)(null);
68
+ const MiniControlsComponent = model.MiniControlsComponent();
69
+ const HeaderComponent = model.HeaderComponent();
70
+ (0, react_1.useEffect)(() => {
71
+ function handleSelectView(e) {
72
+ var _a, _b;
73
+ if (e.target instanceof Element && ((_a = ref.current) === null || _a === void 0 ? void 0 : _a.contains(e.target))) {
74
+ (_b = session.setFocusedViewId) === null || _b === void 0 ? void 0 : _b.call(session, model.id);
75
+ }
76
+ }
77
+ document.addEventListener('mousedown', handleSelectView);
78
+ document.addEventListener('keydown', handleSelectView);
79
+ return () => {
80
+ document.removeEventListener('mousedown', handleSelectView);
81
+ document.removeEventListener('keydown', handleSelectView);
82
+ };
83
+ }, [session, model]);
84
+ return ((0, jsx_runtime_1.jsxs)("div", { className: classes.rel, ref: ref, onMouseLeave: () => {
85
+ session.setHovered(undefined);
86
+ }, onMouseMove: event => {
87
+ const c = ref.current;
88
+ if (!c) {
89
+ return;
90
+ }
91
+ const { tracks } = model;
92
+ const leftPx = event.clientX - c.getBoundingClientRect().left;
93
+ const hoverPosition = model.pxToBp(leftPx);
94
+ const hoverFeature = tracks.find(t => t.displays[0].featureUnderMouse);
95
+ session.setHovered({ hoverPosition, hoverFeature });
96
+ }, children: [(0, jsx_runtime_1.jsxs)("div", { className: classes.header, style: { position: stickyViewHeaders ? 'sticky' : undefined }, children: [(0, jsx_runtime_1.jsx)(HeaderComponent, { model: model }), (0, jsx_runtime_1.jsx)(MiniControlsComponent, { model: model })] }), (0, jsx_runtime_1.jsx)(TracksContainer_1.default, { model: model, children: !tracks.length ? ((0, jsx_runtime_1.jsx)(react_1.Suspense, { fallback: null, children: (0, jsx_runtime_1.jsx)(NoTracksActiveButton, { model: model }) })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [pinnedTracks.length ? ((0, jsx_runtime_1.jsx)(Paper_1.default, { elevation: 6, className: classes.pinnedTracks, style: { top: pinnedTracksTop }, children: pinnedTracks.map(track => ((0, jsx_runtime_1.jsx)(TrackContainer_1.default, { model: model, track: track }, track.id))) })) : null, unpinnedTracks.map(track => ((0, jsx_runtime_1.jsx)(TrackContainer_1.default, { model: model, track: track }, track.id)))] })) })] }));
97
+ });
98
+ exports.default = LinearGenomeViewContainer;
@@ -16,7 +16,6 @@ const useStyles = (0, mui_1.makeStyles)()(theme => ({
16
16
  background: {
17
17
  position: 'absolute',
18
18
  right: 0,
19
- zIndex: 1001,
20
19
  background: theme.palette.background.paper,
21
20
  },
22
21
  focusedBackground: {
@@ -12,7 +12,7 @@ const useStyles = (0, mui_1.makeStyles)()(theme => ({
12
12
  paddingBottom: theme.spacing(1),
13
13
  },
14
14
  top: {
15
- zIndex: 1000,
15
+ zIndex: 800,
16
16
  },
17
17
  }));
18
18
  const NoTracksActiveButton = (0, mobx_react_1.observer)(function ({ model, }) {
@@ -22,7 +22,6 @@ const useStyles = (0, mui_1.makeStyles)()({
22
22
  height: '100%',
23
23
  width: 1,
24
24
  position: 'absolute',
25
- zIndex: 10,
26
25
  },
27
26
  rel: {
28
27
  position: 'relative',
@@ -6,25 +6,48 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const jsx_runtime_1 = require("react/jsx-runtime");
7
7
  const react_1 = require("react");
8
8
  const ui_1 = require("@jbrowse/core/ui");
9
+ const util_1 = require("@jbrowse/core/util");
10
+ const product_core_1 = require("@jbrowse/product-core");
9
11
  const mobx_react_1 = require("mobx-react");
10
12
  const mui_1 = require("tss-react/mui");
11
13
  const RubberbandSpan_1 = __importDefault(require("./RubberbandSpan"));
12
14
  const VerticalGuide_1 = __importDefault(require("./VerticalGuide"));
13
15
  const useRangeSelect_1 = require("./useRangeSelect");
16
+ const consts_1 = require("../consts");
14
17
  const useStyles = (0, mui_1.makeStyles)()({
15
18
  rubberbandControl: {
16
19
  cursor: 'crosshair',
17
20
  width: '100%',
18
21
  minHeight: 8,
22
+ zIndex: 825,
19
23
  },
20
24
  });
21
25
  const Rubberband = (0, mobx_react_1.observer)(function ({ model, ControlComponent = (0, jsx_runtime_1.jsx)("div", {}), }) {
22
26
  const ref = (0, react_1.useRef)(null);
23
27
  const { classes } = useStyles();
28
+ const session = (0, util_1.getSession)(model);
24
29
  const { guideX, rubberbandOn, leftBpOffset, rightBpOffset, numOfBpSelected, width, left, anchorPosition, open, handleMenuItemClick, handleClose, mouseMove, mouseDown, mouseOut, } = (0, useRangeSelect_1.useRangeSelect)(ref, model);
25
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [guideX !== undefined ? ((0, jsx_runtime_1.jsx)(VerticalGuide_1.default, { model: model, coordX: guideX })) : rubberbandOn ? ((0, jsx_runtime_1.jsx)(RubberbandSpan_1.default, { leftBpOffset: leftBpOffset, rightBpOffset: rightBpOffset, numOfBpSelected: numOfBpSelected, width: width, left: left })) : null, anchorPosition ? ((0, jsx_runtime_1.jsx)(ui_1.Menu, { anchorReference: "anchorPosition", anchorPosition: {
30
+ let stickyViewHeaders = false;
31
+ if ((0, product_core_1.isSessionWithMultipleViews)(session)) {
32
+ ;
33
+ ({ stickyViewHeaders } = session);
34
+ }
35
+ let rubberbandControlTop = 0;
36
+ if (stickyViewHeaders) {
37
+ rubberbandControlTop = ui_1.VIEW_HEADER_HEIGHT;
38
+ if (!model.hideHeader) {
39
+ rubberbandControlTop += consts_1.HEADER_BAR_HEIGHT;
40
+ if (!model.hideHeaderOverview) {
41
+ rubberbandControlTop += consts_1.HEADER_OVERVIEW_HEIGHT;
42
+ }
43
+ }
44
+ }
45
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [guideX !== undefined ? ((0, jsx_runtime_1.jsx)(VerticalGuide_1.default, { model: model, coordX: guideX })) : rubberbandOn ? ((0, jsx_runtime_1.jsx)(RubberbandSpan_1.default, { leftBpOffset: leftBpOffset, rightBpOffset: rightBpOffset, numOfBpSelected: numOfBpSelected, width: width, left: left, top: rubberbandControlTop, sticky: stickyViewHeaders })) : null, anchorPosition ? ((0, jsx_runtime_1.jsx)(ui_1.Menu, { anchorReference: "anchorPosition", anchorPosition: {
26
46
  left: anchorPosition.clientX,
27
47
  top: anchorPosition.clientY,
28
- }, onMenuItemClick: handleMenuItemClick, open: open, onClose: handleClose, menuItems: model.rubberBandMenuItems() })) : null, (0, jsx_runtime_1.jsx)("div", { "data-testid": "rubberband_controls", className: classes.rubberbandControl, ref: ref, onMouseDown: mouseDown, onMouseMove: mouseMove, onMouseOut: mouseOut, children: ControlComponent })] }));
48
+ }, onMenuItemClick: handleMenuItemClick, open: open, onClose: handleClose, menuItems: model.rubberBandMenuItems() })) : null, (0, jsx_runtime_1.jsx)("div", { "data-testid": "rubberband_controls", className: classes.rubberbandControl, style: {
49
+ top: rubberbandControlTop,
50
+ position: stickyViewHeaders ? 'sticky' : undefined,
51
+ }, ref: ref, onMouseDown: mouseDown, onMouseMove: mouseMove, onMouseOut: mouseOut, children: ControlComponent })] }));
29
52
  });
30
53
  exports.default = Rubberband;
@@ -3,11 +3,13 @@ interface Offset {
3
3
  refName?: string;
4
4
  oob?: boolean;
5
5
  }
6
- export default function RubberbandSpan({ leftBpOffset, rightBpOffset, numOfBpSelected, left, width, }: {
6
+ export default function RubberbandSpan({ leftBpOffset, rightBpOffset, numOfBpSelected, left, width, top, sticky, }: {
7
7
  leftBpOffset: Offset;
8
8
  rightBpOffset: Offset;
9
9
  numOfBpSelected?: number;
10
10
  left: number;
11
11
  width: number;
12
+ top?: number;
13
+ sticky?: boolean;
12
14
  }): import("react/jsx-runtime").JSX.Element;
13
15
  export {};
@@ -14,9 +14,8 @@ const useStyles = (0, mui_1.makeStyles)()(theme => {
14
14
  height: '100%',
15
15
  background,
16
16
  position: 'absolute',
17
- zIndex: 10,
17
+ zIndex: 830,
18
18
  textAlign: 'center',
19
- overflow: 'hidden',
20
19
  },
21
20
  rubberbandControl: {
22
21
  cursor: 'crosshair',
@@ -46,10 +45,13 @@ function Tooltip({ anchorEl, side, text, }) {
46
45
  horizontal: side === 'left' ? 'left' : 'right',
47
46
  }, keepMounted: true, disableRestoreFocus: true, children: (0, jsx_runtime_1.jsx)(material_1.Typography, { children: text }) }));
48
47
  }
49
- function RubberbandSpan({ leftBpOffset, rightBpOffset, numOfBpSelected, left, width, }) {
48
+ function RubberbandSpan({ leftBpOffset, rightBpOffset, numOfBpSelected, left, width, top = 0, sticky = false, }) {
50
49
  const { classes } = useStyles();
51
50
  const [anchorEl, setAnchorEl] = (0, react_1.useState)(null);
52
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [anchorEl ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Tooltip, { side: "left", anchorEl: anchorEl, text: (0, util_1.stringify)(leftBpOffset) }), (0, jsx_runtime_1.jsx)(Tooltip, { side: "right", anchorEl: anchorEl, text: (0, util_1.stringify)(rightBpOffset) })] })) : null, (0, jsx_runtime_1.jsx)("div", { ref: el => {
53
- setAnchorEl(el);
54
- }, className: classes.rubberband, style: { left, width }, children: numOfBpSelected ? ((0, jsx_runtime_1.jsxs)(material_1.Typography, { variant: "h6", className: classes.rubberbandText, children: [(0, util_1.toLocale)(numOfBpSelected), " bp"] })) : null })] }));
51
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [anchorEl ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Tooltip, { side: "left", anchorEl: anchorEl, text: (0, util_1.stringify)(leftBpOffset) }), (0, jsx_runtime_1.jsx)(Tooltip, { side: "right", anchorEl: anchorEl, text: (0, util_1.stringify)(rightBpOffset) })] })) : null, (0, jsx_runtime_1.jsx)("div", { className: classes.rubberband, style: { left, width }, children: numOfBpSelected ? ((0, jsx_runtime_1.jsxs)(material_1.Typography, { ref: el => {
52
+ setAnchorEl(el);
53
+ }, variant: "h6", className: classes.rubberbandText, style: {
54
+ top,
55
+ position: sticky ? 'sticky' : undefined,
56
+ }, children: [(0, util_1.toLocale)(numOfBpSelected), " bp"] })) : null })] }));
55
57
  }
@@ -8,6 +8,7 @@ const react_1 = require("react");
8
8
  const material_1 = require("@mui/material");
9
9
  const mobx_react_1 = require("mobx-react");
10
10
  const mui_1 = require("tss-react/mui");
11
+ const Gridlines_1 = __importDefault(require("./Gridlines"));
11
12
  const ScalebarCoordinateLabels_1 = __importDefault(require("./ScalebarCoordinateLabels"));
12
13
  const ScalebarRefNameLabels_1 = __importDefault(require("./ScalebarRefNameLabels"));
13
14
  const useStyles = (0, mui_1.makeStyles)()({
@@ -17,7 +18,6 @@ const useStyles = (0, mui_1.makeStyles)()({
17
18
  },
18
19
  zoomContainer: {
19
20
  position: 'relative',
20
- zIndex: 1,
21
21
  },
22
22
  scalebar: {
23
23
  position: 'absolute',
@@ -29,7 +29,7 @@ const Scalebar = (0, mobx_react_1.observer)((0, react_1.forwardRef)(function Sca
29
29
  const { classes, cx } = useStyles();
30
30
  const { staticBlocks, offsetPx, scaleFactor } = model;
31
31
  const offsetLeft = staticBlocks.offsetPx - offsetPx;
32
- return ((0, jsx_runtime_1.jsxs)(material_1.Paper, { "data-resizer": "true", className: cx(classes.container, className), variant: "outlined", ref: ref, style: style, ...other, children: [(0, jsx_runtime_1.jsx)("div", { className: classes.zoomContainer, style: {
32
+ return ((0, jsx_runtime_1.jsxs)(material_1.Paper, { "data-resizer": "true", className: cx(classes.container, className), variant: "outlined", ref: ref, style: style, ...other, children: [(0, jsx_runtime_1.jsx)(Gridlines_1.default, { model: model, offset: 1 }), (0, jsx_runtime_1.jsx)("div", { className: classes.zoomContainer, style: {
33
33
  transform: scaleFactor !== 1 ? `scaleX(${scaleFactor})` : undefined,
34
34
  }, children: (0, jsx_runtime_1.jsx)("div", { className: classes.scalebar, style: {
35
35
  left: offsetLeft - 1,
@@ -11,31 +11,36 @@ const material_1 = require("@mui/material");
11
11
  const mobx_react_1 = require("mobx-react");
12
12
  const mobx_state_tree_1 = require("mobx-state-tree");
13
13
  const mui_1 = require("tss-react/mui");
14
+ const Gridlines_1 = __importDefault(require("./Gridlines"));
14
15
  const TrackLabelContainer_1 = __importDefault(require("./TrackLabelContainer"));
15
16
  const TrackRenderingContainer_1 = __importDefault(require("./TrackRenderingContainer"));
16
17
  const useStyles = (0, mui_1.makeStyles)()({
17
18
  root: {
18
19
  marginTop: 2,
20
+ overflow: 'hidden',
21
+ position: 'relative',
22
+ },
23
+ unpinnedTrack: {
24
+ background: 'none',
19
25
  },
20
26
  resizeHandle: {
21
27
  height: 3,
22
28
  boxSizing: 'border-box',
23
29
  position: 'relative',
24
- zIndex: 2,
25
30
  },
26
31
  });
27
32
  const TrackContainer = (0, mobx_react_1.observer)(function ({ model, track, }) {
28
- const { classes } = useStyles();
33
+ const { classes, cx } = useStyles();
29
34
  const display = track.displays[0];
30
35
  const { draggingTrackId, showTrackOutlines } = model;
31
36
  const ref = (0, react_1.useRef)(null);
32
- return ((0, jsx_runtime_1.jsxs)(material_1.Paper, { ref: ref, className: classes.root, variant: showTrackOutlines ? 'outlined' : undefined, elevation: showTrackOutlines ? undefined : 0, onClick: event => {
37
+ return ((0, jsx_runtime_1.jsxs)(material_1.Paper, { ref: ref, className: cx(classes.root, track.pinned ? null : classes.unpinnedTrack), variant: showTrackOutlines ? 'outlined' : undefined, elevation: showTrackOutlines ? undefined : 0, onClick: event => {
33
38
  var _a;
34
39
  if (event.detail === 2 && !track.displays[0].featureIdUnderMouse) {
35
40
  const left = ((_a = ref.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect().left) || 0;
36
41
  model.zoomTo(model.bpPerPx / 2, event.clientX - left, true);
37
42
  }
38
- }, children: [(0, jsx_runtime_1.jsx)(TrackLabelContainer_1.default, { track: track, view: model }), (0, jsx_runtime_1.jsx)(ErrorBoundary_1.ErrorBoundary, { FallbackComponent: e => (0, jsx_runtime_1.jsx)(ui_1.ErrorMessage, { error: e.error }), children: (0, jsx_runtime_1.jsx)(TrackRenderingContainer_1.default, { model: model, track: track, onDragEnter: () => {
43
+ }, children: [track.pinned ? (0, jsx_runtime_1.jsx)(Gridlines_1.default, { model: model, offset: 1 }) : null, (0, jsx_runtime_1.jsx)(TrackLabelContainer_1.default, { track: track, view: model }), (0, jsx_runtime_1.jsx)(ErrorBoundary_1.ErrorBoundary, { FallbackComponent: e => (0, jsx_runtime_1.jsx)(ui_1.ErrorMessage, { error: e.error }), children: (0, jsx_runtime_1.jsx)(TrackRenderingContainer_1.default, { model: model, track: track, onDragEnter: () => {
39
44
  if ((0, mobx_state_tree_1.isAlive)(display) &&
40
45
  draggingTrackId !== undefined &&
41
46
  draggingTrackId !== display.id) {
@@ -34,7 +34,7 @@ const TrackLabel = (0, mobx_react_1.observer)((0, react_1.forwardRef)(function T
34
34
  const view = (0, util_1.getContainingView)(track);
35
35
  const session = (0, util_1.getSession)(track);
36
36
  const trackConf = track.configuration;
37
- const minimized = track.minimized;
37
+ const { minimized } = track;
38
38
  const trackId = (0, configuration_1.getConf)(track, 'trackId');
39
39
  const trackName = (0, tracks_1.getTrackName)(trackConf, session);
40
40
  return ((0, jsx_runtime_1.jsxs)(material_1.Paper, { ref: ref, className: cx(className, classes.root), onClick: event => {
@@ -9,7 +9,7 @@ const mui_1 = require("tss-react/mui");
9
9
  const TrackLabel_1 = __importDefault(require("./TrackLabel"));
10
10
  const useStyles = (0, mui_1.makeStyles)()({
11
11
  trackLabel: {
12
- zIndex: 3,
12
+ zIndex: 2,
13
13
  },
14
14
  trackLabelOffset: {
15
15
  position: 'relative',
@@ -13,6 +13,7 @@ const KeyboardDoubleArrowDown_1 = __importDefault(require("@mui/icons-material/K
13
13
  const KeyboardDoubleArrowUp_1 = __importDefault(require("@mui/icons-material/KeyboardDoubleArrowUp"));
14
14
  const Minimize_1 = __importDefault(require("@mui/icons-material/Minimize"));
15
15
  const MoreVert_1 = __importDefault(require("@mui/icons-material/MoreVert"));
16
+ const PushPin_1 = __importDefault(require("@mui/icons-material/PushPin"));
16
17
  const mobx_react_1 = require("mobx-react");
17
18
  const TrackLabelMenu = (0, mobx_react_1.observer)(function ({ track, }) {
18
19
  var _a;
@@ -20,7 +21,27 @@ const TrackLabelMenu = (0, mobx_react_1.observer)(function ({ track, }) {
20
21
  const session = (0, util_1.getSession)(track);
21
22
  const trackConf = track.configuration;
22
23
  const minimized = track.minimized;
24
+ const pinned = track.pinned;
25
+ let lgvHasParentView;
26
+ try {
27
+ (0, util_1.getContainingView)(view);
28
+ lgvHasParentView = true;
29
+ }
30
+ catch (error) {
31
+ lgvHasParentView = false;
32
+ }
23
33
  const items = [
34
+ ...(lgvHasParentView
35
+ ? []
36
+ : [
37
+ {
38
+ label: pinned ? 'Unpin track' : 'Pin track',
39
+ icon: PushPin_1.default,
40
+ onClick: () => {
41
+ track.setPinned(!pinned);
42
+ },
43
+ },
44
+ ]),
24
45
  {
25
46
  label: 'Track order',
26
47
  type: 'subMenu',
@@ -19,7 +19,6 @@ const useStyles = (0, mui_1.makeStyles)()({
19
19
  whiteSpace: 'nowrap',
20
20
  position: 'relative',
21
21
  background: 'none',
22
- zIndex: 2,
23
22
  },
24
23
  });
25
24
  const TrackRenderingContainer = (0, mobx_react_1.observer)(function ({ model, track, onDragEnter, }) {