@jbrowse/plugin-alignments 2.10.1 → 2.10.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 (81) hide show
  1. package/dist/AlignmentsFeatureDetail/AlignmentsFeatureDetail.d.ts +2 -2
  2. package/dist/AlignmentsFeatureDetail/AlignmentsFeatureDetail.js +10 -113
  3. package/dist/AlignmentsFeatureDetail/BreakendOptionDialog.d.ts +12 -0
  4. package/dist/AlignmentsFeatureDetail/BreakendOptionDialog.js +89 -0
  5. package/dist/AlignmentsFeatureDetail/Formatter.d.ts +4 -0
  6. package/dist/AlignmentsFeatureDetail/Formatter.js +47 -0
  7. package/dist/AlignmentsFeatureDetail/LaunchBreakpointSplitViewPanel.d.ts +9 -0
  8. package/dist/AlignmentsFeatureDetail/LaunchBreakpointSplitViewPanel.js +92 -0
  9. package/dist/AlignmentsFeatureDetail/PairLink.d.ts +6 -0
  10. package/dist/AlignmentsFeatureDetail/PairLink.js +16 -0
  11. package/dist/AlignmentsFeatureDetail/SuppAlignments.d.ts +8 -0
  12. package/dist/AlignmentsFeatureDetail/SuppAlignments.js +26 -0
  13. package/dist/AlignmentsFeatureDetail/SuppAlignmentsLocStrings.d.ts +6 -0
  14. package/dist/AlignmentsFeatureDetail/{AlignmentsFeatureSuppAligns.js → SuppAlignmentsLocStrings.js} +8 -7
  15. package/dist/AlignmentsFeatureDetail/configSchema.d.ts +1 -0
  16. package/dist/AlignmentsFeatureDetail/configSchema.js +5 -0
  17. package/dist/AlignmentsFeatureDetail/getSAFeatures.d.ts +23 -0
  18. package/dist/AlignmentsFeatureDetail/getSAFeatures.js +41 -0
  19. package/dist/AlignmentsFeatureDetail/index.d.ts +1 -50
  20. package/dist/AlignmentsFeatureDetail/index.js +6 -17
  21. package/dist/AlignmentsFeatureDetail/launchBreakpointSplitView.d.ts +22 -0
  22. package/dist/AlignmentsFeatureDetail/launchBreakpointSplitView.js +50 -0
  23. package/dist/AlignmentsFeatureDetail/stateModelFactory.d.ts +51 -0
  24. package/dist/AlignmentsFeatureDetail/stateModelFactory.js +12 -0
  25. package/dist/AlignmentsFeatureDetail/tagInfo.d.ts +63 -0
  26. package/dist/AlignmentsFeatureDetail/tagInfo.js +66 -0
  27. package/dist/BamAdapter/BamAdapter.js +3 -1
  28. package/dist/CramAdapter/CramAdapter.js +3 -1
  29. package/dist/LinearPileupDisplay/SharedLinearPileupDisplayMixin.d.ts +20 -20
  30. package/dist/LinearPileupDisplay/SharedLinearPileupDisplayMixin.js +8 -8
  31. package/dist/LinearPileupDisplay/model.d.ts +15 -24
  32. package/dist/LinearPileupDisplay/model.js +4 -4
  33. package/dist/LinearReadArcsDisplay/model.d.ts +8 -8
  34. package/dist/LinearReadArcsDisplay/model.js +2 -2
  35. package/dist/LinearReadCloudDisplay/model.d.ts +13 -7
  36. package/dist/LinearReadCloudDisplay/model.js +2 -2
  37. package/dist/LinearSNPCoverageDisplay/components/Tooltip.js +5 -2
  38. package/esm/AlignmentsFeatureDetail/AlignmentsFeatureDetail.d.ts +2 -2
  39. package/esm/AlignmentsFeatureDetail/AlignmentsFeatureDetail.js +12 -92
  40. package/esm/AlignmentsFeatureDetail/BreakendOptionDialog.d.ts +12 -0
  41. package/esm/AlignmentsFeatureDetail/BreakendOptionDialog.js +64 -0
  42. package/esm/AlignmentsFeatureDetail/Formatter.d.ts +4 -0
  43. package/esm/AlignmentsFeatureDetail/Formatter.js +18 -0
  44. package/esm/AlignmentsFeatureDetail/LaunchBreakpointSplitViewPanel.d.ts +9 -0
  45. package/esm/AlignmentsFeatureDetail/LaunchBreakpointSplitViewPanel.js +66 -0
  46. package/esm/AlignmentsFeatureDetail/PairLink.d.ts +6 -0
  47. package/esm/AlignmentsFeatureDetail/PairLink.js +10 -0
  48. package/esm/AlignmentsFeatureDetail/SuppAlignments.d.ts +8 -0
  49. package/esm/AlignmentsFeatureDetail/SuppAlignments.js +20 -0
  50. package/esm/AlignmentsFeatureDetail/SuppAlignmentsLocStrings.d.ts +6 -0
  51. package/esm/AlignmentsFeatureDetail/{AlignmentsFeatureSuppAligns.js → SuppAlignmentsLocStrings.js} +7 -6
  52. package/esm/AlignmentsFeatureDetail/configSchema.d.ts +1 -0
  53. package/esm/AlignmentsFeatureDetail/configSchema.js +2 -0
  54. package/esm/AlignmentsFeatureDetail/getSAFeatures.d.ts +23 -0
  55. package/esm/AlignmentsFeatureDetail/getSAFeatures.js +37 -0
  56. package/esm/AlignmentsFeatureDetail/index.d.ts +1 -50
  57. package/esm/AlignmentsFeatureDetail/index.js +4 -13
  58. package/esm/AlignmentsFeatureDetail/launchBreakpointSplitView.d.ts +22 -0
  59. package/esm/AlignmentsFeatureDetail/launchBreakpointSplitView.js +46 -0
  60. package/esm/AlignmentsFeatureDetail/stateModelFactory.d.ts +51 -0
  61. package/esm/AlignmentsFeatureDetail/stateModelFactory.js +8 -0
  62. package/esm/AlignmentsFeatureDetail/tagInfo.d.ts +63 -0
  63. package/esm/AlignmentsFeatureDetail/tagInfo.js +63 -0
  64. package/esm/BamAdapter/BamAdapter.js +3 -1
  65. package/esm/CramAdapter/CramAdapter.js +3 -1
  66. package/esm/LinearPileupDisplay/SharedLinearPileupDisplayMixin.d.ts +20 -20
  67. package/esm/LinearPileupDisplay/SharedLinearPileupDisplayMixin.js +8 -8
  68. package/esm/LinearPileupDisplay/model.d.ts +15 -24
  69. package/esm/LinearPileupDisplay/model.js +4 -4
  70. package/esm/LinearReadArcsDisplay/model.d.ts +8 -8
  71. package/esm/LinearReadArcsDisplay/model.js +2 -2
  72. package/esm/LinearReadCloudDisplay/model.d.ts +13 -7
  73. package/esm/LinearReadCloudDisplay/model.js +2 -2
  74. package/esm/LinearSNPCoverageDisplay/components/Tooltip.js +5 -2
  75. package/package.json +2 -2
  76. package/dist/AlignmentsFeatureDetail/AlignmentsFeatureSuppAligns.d.ts +0 -6
  77. package/esm/AlignmentsFeatureDetail/AlignmentsFeatureSuppAligns.d.ts +0 -6
  78. /package/dist/AlignmentsFeatureDetail/{AlignmentsFeatureFlags.d.ts → Flags.d.ts} +0 -0
  79. /package/dist/AlignmentsFeatureDetail/{AlignmentsFeatureFlags.js → Flags.js} +0 -0
  80. /package/esm/AlignmentsFeatureDetail/{AlignmentsFeatureFlags.d.ts → Flags.d.ts} +0 -0
  81. /package/esm/AlignmentsFeatureDetail/{AlignmentsFeatureFlags.js → Flags.js} +0 -0
@@ -40,8 +40,8 @@ const Sort_1 = __importDefault(require("@mui/icons-material/Sort"));
40
40
  const SharedLinearPileupDisplayMixin_1 = require("./SharedLinearPileupDisplayMixin");
41
41
  const mobx_1 = require("mobx");
42
42
  // async
43
- const SortByTagDlg = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./components/SortByTag'))));
44
- const ModificationsDlg = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./components/ColorByModifications'))));
43
+ const SortByTagDialog = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./components/SortByTag'))));
44
+ const ModificationsDialog = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./components/ColorByModifications'))));
45
45
  /**
46
46
  * #stateModel LinearPileupDisplay
47
47
  * #category display
@@ -265,7 +265,7 @@ function stateModelFactory(configSchema) {
265
265
  label: 'Sort by tag...',
266
266
  onClick: () => {
267
267
  (0, util_1.getSession)(self).queueDialog(handleClose => [
268
- SortByTagDlg,
268
+ SortByTagDialog,
269
269
  { model: self, handleClose },
270
270
  ]);
271
271
  },
@@ -287,7 +287,7 @@ function stateModelFactory(configSchema) {
287
287
  label: 'Modifications or methylation',
288
288
  onClick: () => {
289
289
  (0, util_1.getSession)(self).queueDialog(doneCallback => [
290
- ModificationsDlg,
290
+ ModificationsDialog,
291
291
  { model: self, handleClose: doneCallback },
292
292
  ]);
293
293
  },
@@ -61,7 +61,9 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
61
61
  } & import("mobx-state-tree").IStateTreeNode<import("mobx-state-tree").IModelType<{
62
62
  id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
63
63
  type: import("mobx-state-tree").ISimpleType<string>;
64
- rpcDriverName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
64
+ rpcDriverName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>; /**
65
+ * #property
66
+ */
65
67
  }, {
66
68
  rendererTypeName: string;
67
69
  error: unknown;
@@ -80,7 +82,9 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
80
82
  error: unknown;
81
83
  message: string | undefined;
82
84
  } & import("mobx-state-tree").IStateTreeNode<import("mobx-state-tree").IModelType<{
83
- id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
85
+ id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>; /**
86
+ * #action
87
+ */
84
88
  type: import("mobx-state-tree").ISimpleType<string>;
85
89
  rpcDriverName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
86
90
  }, {
@@ -90,17 +94,13 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
90
94
  }, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
91
95
  }> | null;
92
96
  readonly adapterConfig: any;
93
- readonly parentTrack: any; /**
94
- * #action
95
- */
97
+ readonly parentTrack: any;
96
98
  renderProps(): any;
97
99
  readonly rendererType: import("@jbrowse/core/pluggableElementTypes").RendererType;
98
100
  readonly DisplayMessageComponent: React.FC<any> | undefined;
99
101
  trackMenuItems(): import("@jbrowse/core/ui").MenuItem[];
100
102
  readonly viewMenuActions: import("@jbrowse/core/ui").MenuItem[];
101
- regionCannotBeRendered(): null; /**
102
- * #getter
103
- */
103
+ regionCannotBeRendered(): null;
104
104
  } & {
105
105
  setMessage(arg?: string | undefined): void;
106
106
  setError(error?: unknown): void; /**
@@ -38,7 +38,7 @@ const ClearAll_1 = __importDefault(require("@mui/icons-material/ClearAll"));
38
38
  // locals
39
39
  const shared_1 = require("../shared");
40
40
  // async
41
- const FilterByTagDlg = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('../shared/FilterByTag'))));
41
+ const FilterByTagDialog = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('../shared/FilterByTag'))));
42
42
  /**
43
43
  * #stateModel LinearReadArcsDisplay
44
44
  * the arc display is a non-block-based track, so draws to a single canvas and
@@ -220,7 +220,7 @@ function stateModelFactory(configSchema) {
220
220
  icon: ClearAll_1.default,
221
221
  onClick: () => {
222
222
  (0, util_1.getSession)(self).queueDialog(handleClose => [
223
- FilterByTagDlg,
223
+ FilterByTagDialog,
224
224
  { model: self, handleClose },
225
225
  ]);
226
226
  },
@@ -44,6 +44,14 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
44
44
  message: string | undefined;
45
45
  } & {
46
46
  readonly RenderingComponent: React.FC<{
47
+ /**
48
+ * #stateModel LinearReadCloudDisplay
49
+ * it is not a block based track, hence not BaseLinearDisplay
50
+ * extends
51
+ * - [BaseDisplay](../basedisplay)
52
+ * - [TrackHeightMixin](../trackheightmixin)
53
+ * - [FeatureDensityMixin](../featuredensitymixin)
54
+ */
47
55
  model: {
48
56
  id: string;
49
57
  type: string;
@@ -55,9 +63,6 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
55
63
  } & import("mobx-state-tree").IStateTreeNode<import("mobx-state-tree").IModelType<{
56
64
  id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
57
65
  type: import("mobx-state-tree").ISimpleType<string>;
58
- /**
59
- * #property
60
- */
61
66
  rpcDriverName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
62
67
  }, {
63
68
  rendererTypeName: string;
@@ -78,7 +83,11 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
78
83
  message: string | undefined;
79
84
  } & import("mobx-state-tree").IStateTreeNode<import("mobx-state-tree").IModelType<{
80
85
  id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
81
- type: import("mobx-state-tree").ISimpleType<string>;
86
+ type: import("mobx-state-tree").ISimpleType<string>; /**
87
+ * #action
88
+ * internal, a reference to a HTMLCanvas because we use a autorun to draw
89
+ * the canvas
90
+ */
82
91
  rpcDriverName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
83
92
  }, {
84
93
  rendererTypeName: string;
@@ -130,9 +139,6 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
130
139
  readonly regionTooLarge: boolean;
131
140
  readonly regionTooLargeReason: string;
132
141
  } & {
133
- /**
134
- * #method
135
- */
136
142
  regionCannotBeRenderedText(_region: import("@jbrowse/core/util").Region): "" | "Force load to see features";
137
143
  regionCannotBeRendered(_region: import("@jbrowse/core/util").Region): React.JSX.Element | null;
138
144
  } & {
@@ -38,7 +38,7 @@ const ClearAll_1 = __importDefault(require("@mui/icons-material/ClearAll"));
38
38
  // locals
39
39
  const shared_1 = require("../shared");
40
40
  // async
41
- const FilterByTagDlg = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('../shared/FilterByTag'))));
41
+ const FilterByTagDialog = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('../shared/FilterByTag'))));
42
42
  /**
43
43
  * #stateModel LinearReadCloudDisplay
44
44
  * it is not a block based track, hence not BaseLinearDisplay
@@ -170,7 +170,7 @@ function stateModelFactory(configSchema) {
170
170
  icon: ClearAll_1.default,
171
171
  onClick: () => {
172
172
  (0, util_1.getSession)(self).queueDialog(handleClose => [
173
- FilterByTagDlg,
173
+ FilterByTagDialog,
174
174
  { model: self, handleClose },
175
175
  ]);
176
176
  },
@@ -5,8 +5,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const react_1 = __importDefault(require("react"));
7
7
  const mobx_react_1 = require("mobx-react");
8
+ const util_1 = require("@jbrowse/core/util");
8
9
  const plugin_wiggle_1 = require("@jbrowse/plugin-wiggle");
9
- const en = (n) => n.toLocaleString('en-US');
10
10
  const toP = (s = 0) => +(+s).toFixed(1);
11
11
  const pct = (n, total) => `${toP((n / (total || 1)) * 100)}%`;
12
12
  const TooltipContents = react_1.default.forwardRef(function TooltipContents2({ feature }, reactRef) {
@@ -14,7 +14,10 @@ const TooltipContents = react_1.default.forwardRef(function TooltipContents2({ f
14
14
  const end = feature.get('end');
15
15
  const name = feature.get('refName');
16
16
  const { refbase, all, total, ref, '-1': rn1, '1': r1, '0': r0, ...info } = feature.get('snpinfo');
17
- const loc = [name, start === end ? en(start) : `${en(start)}..${en(end)}`]
17
+ const loc = [
18
+ name,
19
+ start === end ? (0, util_1.toLocale)(start) : `${(0, util_1.toLocale)(start)}..${(0, util_1.toLocale)(end)}`,
20
+ ]
18
21
  .filter(f => !!f)
19
22
  .join(':');
20
23
  return (react_1.default.createElement("div", { ref: reactRef },
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
- import { IAnyStateTreeNode } from 'mobx-state-tree';
2
+ import { AlignmentFeatureWidgetModel } from './stateModelFactory';
3
3
  declare const AlignmentsFeatureDetails: (props: {
4
- model: IAnyStateTreeNode;
4
+ model: AlignmentFeatureWidgetModel;
5
5
  }) => React.JSX.Element;
6
6
  export default AlignmentsFeatureDetails;
@@ -1,97 +1,17 @@
1
- import React, { useState } from 'react';
2
- import { Link, Paper } from '@mui/material';
1
+ import React from 'react';
2
+ import { Paper } from '@mui/material';
3
3
  import { observer } from 'mobx-react';
4
- import copy from 'copy-to-clipboard';
5
4
  import clone from 'clone';
6
5
  import { FeatureDetails } from '@jbrowse/core/BaseFeatureWidget/BaseFeatureDetail';
7
6
  // locals
8
- import { getTag, navToLoc } from './util';
9
- import SupplementaryAlignments from './AlignmentsFeatureSuppAligns';
10
- import AlignmentFlags from './AlignmentsFeatureFlags';
7
+ import { getTag } from './util';
8
+ import { tags } from './tagInfo';
9
+ // local components
10
+ import SuppAlignments from './SuppAlignments';
11
+ import Flags from './Flags';
12
+ import PairLink from './PairLink';
13
+ import Formatter from './Formatter';
11
14
  const omit = ['clipPos', 'flags'];
12
- const tags = {
13
- AM: 'The smallest template-independent mapping quality in the template',
14
- AS: 'Alignment score generated by aligner',
15
- BC: 'Barcode sequence identifying the sample',
16
- BQ: 'Offset to base alignment quality (BAQ)',
17
- BZ: 'Phred quality of the unique molecular barcode bases in the {OX} tag',
18
- CB: 'Cell identifier',
19
- CC: 'Reference name of the next hit',
20
- CM: 'Edit distance between the color sequence and the color reference (see also {NM})',
21
- CO: 'Free-text comments',
22
- CP: 'Leftmost coordinate of the next hit',
23
- CQ: 'Color read base qualities',
24
- CR: 'Cellular barcode sequence bases (uncorrected)',
25
- CS: 'Color read sequence',
26
- CT: 'Complete read annotation tag, used for consensus annotation dummy features',
27
- CY: 'Phred quality of the cellular barcode sequence in the {CR} tag',
28
- E2: 'The 2nd most likely base calls',
29
- FI: 'The index of segment in the template',
30
- FS: 'Segment suffix',
31
- FZ: 'Flow signal intensities',
32
- GC: 'Reserved for backwards compatibility reasons',
33
- GQ: 'Reserved for backwards compatibility reasons',
34
- GS: 'Reserved for backwards compatibility reasons',
35
- H0: 'Number of perfect hits',
36
- H1: 'Number of 1-difference hits (see also {NM})',
37
- H2: 'Number of 2-difference hits',
38
- HI: 'Query hit index',
39
- IH: 'Query hit total count',
40
- LB: 'Library',
41
- MC: 'CIGAR string for mate/next segment',
42
- MD: 'String encoding mismatched and deleted reference bases',
43
- MF: 'Reserved for backwards compatibility reasons',
44
- MI: 'Molecular identifier; a string that uniquely identifies the molecule from which the record was derived',
45
- ML: 'Base modification probabilities',
46
- MM: 'Base modifications / methylation ',
47
- MQ: 'Mapping quality of the mate/next segment',
48
- NH: 'Number of reported alignments that contain the query in the current record',
49
- NM: 'Edit distance to the reference',
50
- OA: 'Original alignment',
51
- OC: 'Original CIGAR (deprecated; use {OA} instead)',
52
- OP: 'Original mapping position (deprecated; use {OA} instead)',
53
- OQ: 'Original base quality',
54
- OX: 'Original unique molecular barcode bases',
55
- PG: 'Program',
56
- PQ: 'Phred likelihood of the template',
57
- PT: 'Read annotations for parts of the padded read sequence',
58
- PU: 'Platform unit',
59
- Q2: 'Phred quality of the mate/next segment sequence in the {R2} tag',
60
- QT: 'Phred quality of the sample barcode sequence in the {BC} tag',
61
- QX: 'Quality score of the unique molecular identifier in the {RX} tag',
62
- R2: 'Sequence of the mate/next segment in the template',
63
- RG: 'Read group',
64
- RT: 'Reserved for backwards compatibility reasons',
65
- RX: 'Sequence bases of the (possibly corrected) unique molecular identifier',
66
- S2: 'Reserved for backwards compatibility reasons',
67
- SA: 'Other canonical alignments in a chimeric alignment',
68
- SM: 'Template-independent mapping quality',
69
- SQ: 'Reserved for backwards compatibility reasons',
70
- TC: 'The number of segments in the template',
71
- TS: 'Transcript strand',
72
- U2: 'Phred probability of the 2nd call being wrong conditional on the best being wrong',
73
- UQ: 'Phred likelihood of the segment, conditional on the mapping being correct',
74
- };
75
- function Formatter({ value }) {
76
- const [show, setShow] = useState(false);
77
- const [copied, setCopied] = useState(false);
78
- const display = String(value);
79
- return display.length > 100 ? (React.createElement(React.Fragment, null,
80
- React.createElement("button", { type: "button", onClick: () => {
81
- copy(display);
82
- setCopied(true);
83
- setTimeout(() => setCopied(false), 700);
84
- } }, copied ? 'Copied to clipboard' : 'Copy'),
85
- React.createElement("button", { type: "button", onClick: () => setShow(val => !val) }, show ? 'Show less' : 'Show more'),
86
- React.createElement("div", null, show ? display : `${display.slice(0, 100)}...`))) : (React.createElement("div", null, display));
87
- }
88
- function PairLink({ locString, model, }) {
89
- return (React.createElement(Link, { onClick: event => {
90
- event.preventDefault();
91
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
92
- navToLoc(locString, model);
93
- }, href: "#" }, locString));
94
- }
95
15
  const AlignmentsFeatureDetails = observer(function (props) {
96
16
  const { model } = props;
97
17
  const feat = clone(model.featureData);
@@ -99,8 +19,8 @@ const AlignmentsFeatureDetails = observer(function (props) {
99
19
  return (React.createElement(Paper, { "data-testid": "alignment-side-drawer" },
100
20
  React.createElement(FeatureDetails, { ...props, omit: omit,
101
21
  // @ts-expect-error
102
- descriptions: { ...tags, tags }, feature: feat, formatter: (value, key) => key === 'next_segment_position' ? (React.createElement(PairLink, { model: model, locString: value })) : (React.createElement(Formatter, { value: value })) }),
103
- SA ? React.createElement(SupplementaryAlignments, { model: model, tag: SA }) : null,
104
- feat.flags !== undefined ? (React.createElement(AlignmentFlags, { feature: feat, ...props })) : null));
22
+ descriptions: { ...tags, tags: tags }, feature: feat, formatter: (value, key) => key === 'next_segment_position' ? (React.createElement(PairLink, { model: model, locString: value })) : (React.createElement(Formatter, { value: value })) }),
23
+ SA ? React.createElement(SuppAlignments, { model: model, tag: SA, feature: feat }) : null,
24
+ feat.flags !== undefined ? React.createElement(Flags, { feature: feat, ...props }) : null));
105
25
  });
106
26
  export default AlignmentsFeatureDetails;
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ import { ViewType } from '@jbrowse/core/pluggableElementTypes';
3
+ import { AlignmentFeatureWidgetModel } from './stateModelFactory';
4
+ import { ReducedFeature } from './getSAFeatures';
5
+ declare const BreakendOptionDialog: ({ model, handleClose, f1, f2, }: {
6
+ model: AlignmentFeatureWidgetModel;
7
+ handleClose: () => void;
8
+ f1: ReducedFeature;
9
+ f2: ReducedFeature;
10
+ viewType: ViewType;
11
+ }) => React.JSX.Element;
12
+ export default BreakendOptionDialog;
@@ -0,0 +1,64 @@
1
+ import React, { useState } from 'react';
2
+ import { observer } from 'mobx-react';
3
+ import { Button, Checkbox, DialogActions, DialogContent, FormControlLabel, } from '@mui/material';
4
+ import { makeStyles } from 'tss-react/mui';
5
+ import { getSession } from '@jbrowse/core/util';
6
+ import { Dialog } from '@jbrowse/core/ui';
7
+ import { getBreakpointSplitView } from './launchBreakpointSplitView';
8
+ import { getSnapshot } from 'mobx-state-tree';
9
+ const useStyles = makeStyles()({
10
+ block: {
11
+ display: 'block',
12
+ },
13
+ });
14
+ function stripIds(arr) {
15
+ return arr.map(({ id, displays, ...rest }) => ({
16
+ ...rest,
17
+ displays: displays.map(({ id, ...rest }) => rest),
18
+ }));
19
+ }
20
+ function Checkbox2({ checked, label, onChange, }) {
21
+ const { classes } = useStyles();
22
+ return (React.createElement(FormControlLabel, { className: classes.block, control: React.createElement(Checkbox, { checked: checked, onChange: onChange }), label: label }));
23
+ }
24
+ const BreakendOptionDialog = observer(function ({ model, handleClose, f1, f2, }) {
25
+ const [copyTracks, setCopyTracks] = useState(true);
26
+ const [mirror, setMirror] = useState(true);
27
+ return (React.createElement(Dialog, { open: true, onClose: handleClose, title: "Breakpoint split view options" },
28
+ React.createElement(DialogContent, null,
29
+ React.createElement(Checkbox2, { checked: copyTracks, onChange: event => setCopyTracks(event.target.checked), label: "Copy tracks into the new view" }),
30
+ React.createElement(Checkbox2, { checked: mirror, onChange: event => setMirror(event.target.checked), label: "Mirror tracks vertically in vertically stacked view" })),
31
+ React.createElement(DialogActions, null,
32
+ React.createElement(Button, { onClick: () => {
33
+ const { view } = model;
34
+ const session = getSession(model);
35
+ try {
36
+ const viewSnapshot = getBreakpointSplitView({ view, f1, f2 });
37
+ const [view1, view2] = viewSnapshot.views;
38
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
39
+ const viewTracks = getSnapshot(view.tracks);
40
+ session.addView('BreakpointSplitView', {
41
+ ...viewSnapshot,
42
+ views: [
43
+ {
44
+ ...view1,
45
+ tracks: stripIds(viewTracks),
46
+ offsetPx: view1.offsetPx - view.width / 2 + 100,
47
+ },
48
+ {
49
+ ...view2,
50
+ tracks: stripIds(mirror ? [...viewTracks].reverse() : viewTracks),
51
+ offsetPx: view2.offsetPx - view.width / 2 + 100,
52
+ },
53
+ ],
54
+ });
55
+ }
56
+ catch (e) {
57
+ console.error(e);
58
+ session.notify(`${e}`);
59
+ }
60
+ handleClose();
61
+ }, variant: "contained", color: "primary", autoFocus: true }, "OK"),
62
+ React.createElement(Button, { onClick: () => handleClose(), color: "secondary", variant: "contained" }, "Cancel"))));
63
+ });
64
+ export default BreakendOptionDialog;
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ export default function Formatter({ value }: {
3
+ value: unknown;
4
+ }): React.JSX.Element;
@@ -0,0 +1,18 @@
1
+ import React, { useState } from 'react';
2
+ import copy from 'copy-to-clipboard';
3
+ // this 'show more...' used specifically as a formatter on alignments feature
4
+ // details because long SEQ or CRAM files, even a single div full of a ton of
5
+ // data from a long read, can slow down the rest of the app
6
+ export default function Formatter({ value }) {
7
+ const [show, setShow] = useState(false);
8
+ const [copied, setCopied] = useState(false);
9
+ const display = String(value);
10
+ return display.length > 100 ? (React.createElement(React.Fragment, null,
11
+ React.createElement("button", { type: "button", onClick: () => {
12
+ copy(display);
13
+ setCopied(true);
14
+ setTimeout(() => setCopied(false), 700);
15
+ } }, copied ? 'Copied to clipboard' : 'Copy'),
16
+ React.createElement("button", { type: "button", onClick: () => setShow(val => !val) }, show ? 'Show less' : 'Show more'),
17
+ React.createElement("div", null, show ? display : `${display.slice(0, 100)}...`))) : (React.createElement("div", null, display));
18
+ }
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ import { SimpleFeatureSerialized } from '@jbrowse/core/util';
3
+ import { ViewType } from '@jbrowse/core/pluggableElementTypes';
4
+ import { AlignmentFeatureWidgetModel } from './stateModelFactory';
5
+ export default function LaunchBreakpointSplitViewPanel({ model, feature, viewType, }: {
6
+ model: AlignmentFeatureWidgetModel;
7
+ feature: SimpleFeatureSerialized;
8
+ viewType: ViewType;
9
+ }): React.JSX.Element;
@@ -0,0 +1,66 @@
1
+ import React, { lazy, useEffect, useState } from 'react';
2
+ import { Typography, Link, Tooltip } from '@mui/material';
3
+ import { SimpleFeature, getSession, toLocale, } from '@jbrowse/core/util';
4
+ import { makeStyles } from 'tss-react/mui';
5
+ import { ErrorMessage } from '@jbrowse/core/ui';
6
+ import { getSAFeatures } from './getSAFeatures';
7
+ // lazies
8
+ const BreakendOptionDialog = lazy(() => import('./BreakendOptionDialog'));
9
+ const useStyles = makeStyles()({
10
+ cursor: {
11
+ cursor: 'pointer',
12
+ },
13
+ });
14
+ export default function LaunchBreakpointSplitViewPanel({ model, feature, viewType, }) {
15
+ const { classes } = useStyles();
16
+ const session = getSession(model);
17
+ const { view } = model;
18
+ const [res, setRes] = useState();
19
+ const [error, setError] = useState();
20
+ useEffect(() => {
21
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
22
+ ;
23
+ (async () => {
24
+ try {
25
+ const feats = await getSAFeatures({
26
+ view,
27
+ feature: new SimpleFeature(feature),
28
+ });
29
+ setRes(feats);
30
+ }
31
+ catch (e) {
32
+ setError(e);
33
+ console.error(e);
34
+ }
35
+ })();
36
+ }, [feature, view]);
37
+ const ret = [];
38
+ if (res) {
39
+ for (let i = 0; i < res.length - 1; i++) {
40
+ ret.push([res[i], res[i + 1]]);
41
+ }
42
+ }
43
+ return (React.createElement(React.Fragment, null, ret.length ? (React.createElement("div", null,
44
+ React.createElement(Typography, null, "Launch split views with breakend source and target"),
45
+ error ? React.createElement(ErrorMessage, { error: error }) : null,
46
+ React.createElement("ul", null, ret.map((arg, index) => {
47
+ const [f1, f2] = arg;
48
+ return (React.createElement("li", { key: `${JSON.stringify(arg)}-${index}` },
49
+ React.createElement(Tooltip, { title: "Top panel->Bottom panel" },
50
+ React.createElement(Link, { href: "#", className: classes.cursor, onClick: event => {
51
+ event.preventDefault();
52
+ session.queueDialog(handleClose => [
53
+ BreakendOptionDialog,
54
+ { handleClose, f1, f2, model, viewType },
55
+ ]);
56
+ } },
57
+ f1.refName,
58
+ ":",
59
+ toLocale(f1.strand === 1 ? f1.end : f1.start),
60
+ " ->",
61
+ ' ',
62
+ f2.refName,
63
+ ":",
64
+ toLocale(f2.strand === 1 ? f2.start : f2.end)))));
65
+ })))) : null));
66
+ }
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import { AlignmentFeatureWidgetModel } from './stateModelFactory';
3
+ export default function PairLink({ locString, model, }: {
4
+ locString: string;
5
+ model: AlignmentFeatureWidgetModel;
6
+ }): React.JSX.Element;
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ import { Link } from '@mui/material';
3
+ import { navToLoc } from './util';
4
+ export default function PairLink({ locString, model, }) {
5
+ return (React.createElement(Link, { onClick: event => {
6
+ event.preventDefault();
7
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
8
+ navToLoc(locString, model);
9
+ }, href: "#" }, locString));
10
+ }
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import { SimpleFeatureSerialized } from '@jbrowse/core/util';
3
+ import { AlignmentFeatureWidgetModel } from './stateModelFactory';
4
+ export default function SuppAlignments(props: {
5
+ tag: string;
6
+ model: AlignmentFeatureWidgetModel;
7
+ feature: SimpleFeatureSerialized;
8
+ }): React.JSX.Element;
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ import { BaseCard } from '@jbrowse/core/BaseFeatureWidget/BaseFeatureDetail';
3
+ import { getEnv, getSession } from '@jbrowse/core/util';
4
+ import SuppAlignmentsLocStrings from './SuppAlignmentsLocStrings';
5
+ import LaunchBreakpointSplitViewPanel from './LaunchBreakpointSplitViewPanel';
6
+ export default function SuppAlignments(props) {
7
+ const { model, tag, feature } = props;
8
+ const session = getSession(model);
9
+ const { pluginManager } = getEnv(session);
10
+ let viewType;
11
+ try {
12
+ viewType = pluginManager.getViewType('BreakpointSplitView');
13
+ }
14
+ catch (e) {
15
+ // ignore
16
+ }
17
+ return (React.createElement(BaseCard, { ...props, title: "Supplementary alignments" },
18
+ React.createElement(SuppAlignmentsLocStrings, { model: model, tag: tag }),
19
+ viewType ? (React.createElement(LaunchBreakpointSplitViewPanel, { viewType: viewType, model: model, feature: feature })) : null));
20
+ }
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import { AlignmentFeatureWidgetModel } from './stateModelFactory';
3
+ export default function SuppAlignmentsLocStrings({ tag, model, }: {
4
+ tag: string;
5
+ model: AlignmentFeatureWidgetModel;
6
+ }): React.JSX.Element;
@@ -1,11 +1,10 @@
1
1
  import React from 'react';
2
2
  import { Typography, Link } from '@mui/material';
3
- import { BaseCard } from '@jbrowse/core/BaseFeatureWidget/BaseFeatureDetail';
3
+ // locals
4
4
  import { getLengthOnRef } from '../MismatchParser';
5
5
  import { navToLoc } from './util';
6
- export default function SupplementaryAlignments(props) {
7
- const { tag, model } = props;
8
- return (React.createElement(BaseCard, { ...props, title: "Supplementary alignments" },
6
+ export default function SuppAlignmentsLocStrings({ tag, model, }) {
7
+ return (React.createElement("div", null,
9
8
  React.createElement(Typography, null, "List of supplementary alignment locations"),
10
9
  React.createElement("ul", null, tag
11
10
  .split(';')
@@ -16,7 +15,9 @@ export default function SupplementaryAlignments(props) {
16
15
  const extra = Math.floor(saLength / 5);
17
16
  const start = +saStart;
18
17
  const end = +saStart + saLength;
19
- const locString = `${saRef}:${Math.max(1, start - extra)}-${end + extra}`;
18
+ const sp = start - extra;
19
+ const ep = end + extra;
20
+ const locString = `${saRef}:${Math.max(1, sp)}-${ep}`;
20
21
  const displayStart = start.toLocaleString('en-US');
21
22
  const displayEnd = end.toLocaleString('en-US');
22
23
  const displayString = `${saRef}:${displayStart}-${displayEnd} (${saStrand}) [${saLength}bp]`;
@@ -25,6 +26,6 @@ export default function SupplementaryAlignments(props) {
25
26
  event.preventDefault();
26
27
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
27
28
  navToLoc(locString, model);
28
- }, href: "#" }, displayString)));
29
+ } }, displayString)));
29
30
  }))));
30
31
  }
@@ -0,0 +1 @@
1
+ export declare const configSchema: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined>>;
@@ -0,0 +1,2 @@
1
+ import { ConfigurationSchema } from '@jbrowse/core/configuration';
2
+ export const configSchema = ConfigurationSchema('AlignmentsFeatureWidget', {});
@@ -0,0 +1,23 @@
1
+ import { Feature } from '@jbrowse/core/util';
2
+ import { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view';
3
+ export interface ReducedFeature {
4
+ refName: string;
5
+ start: number;
6
+ clipPos: number;
7
+ end: number;
8
+ strand: number;
9
+ seqLength: number;
10
+ syntenyId?: number;
11
+ uniqueId: string;
12
+ mate: {
13
+ refName: string;
14
+ start: number;
15
+ end: number;
16
+ syntenyId?: number;
17
+ uniqueId?: string;
18
+ };
19
+ }
20
+ export declare function getSAFeatures({ view, feature, }: {
21
+ view: LinearGenomeViewModel;
22
+ feature: Feature;
23
+ }): Promise<ReducedFeature[]>;