@jbrowse/plugin-alignments 2.13.1 → 2.15.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 (155) hide show
  1. package/dist/AlignmentsFeatureDetail/AlignmentsFeatureDetail.js +5 -3
  2. package/dist/AlignmentsFeatureDetail/BreakendOptionDialog.js +12 -4
  3. package/dist/AlignmentsFeatureDetail/Formatter.js +6 -2
  4. package/dist/AlignmentsFeatureDetail/SuppAlignmentsLocStrings.js +4 -2
  5. package/dist/AlignmentsFeatureDetail/getSAFeatures.js +4 -4
  6. package/dist/AlignmentsFeatureDetail/launchBreakpointSplitView.js +2 -2
  7. package/dist/BamAdapter/BamAdapter.js +12 -18
  8. package/dist/BamAdapter/BamSlightlyLazyFeature.js +0 -1
  9. package/dist/CramAdapter/CramAdapter.d.ts +1 -1
  10. package/dist/CramAdapter/CramAdapter.js +7 -6
  11. package/dist/CramAdapter/CramTestAdapters.js +8 -2
  12. package/dist/GuessAlignmentsTypes/index.js +2 -2
  13. package/dist/LinearAlignmentsDisplay/components/AlignmentsDisplay.d.ts +2 -2
  14. package/dist/LinearAlignmentsDisplay/models/model.d.ts +13 -20
  15. package/dist/LinearAlignmentsDisplay/models/model.js +13 -3
  16. package/dist/LinearPileupDisplay/SharedLinearPileupDisplayMixin.d.ts +9 -4
  17. package/dist/LinearPileupDisplay/SharedLinearPileupDisplayMixin.js +41 -22
  18. package/dist/LinearPileupDisplay/components/{ColorByModifications.js → ColorByModificationsDialog.js} +3 -1
  19. package/dist/LinearPileupDisplay/components/{ColorByTag.js → ColorByTagDialog.js} +4 -2
  20. package/dist/LinearPileupDisplay/components/GroupByDialog.d.ts +11 -0
  21. package/dist/LinearPileupDisplay/components/GroupByDialog.js +129 -0
  22. package/dist/LinearPileupDisplay/components/LinearPileupDisplayBlurb.js +1 -3
  23. package/dist/LinearPileupDisplay/components/{SetFeatureHeight.js → SetFeatureHeightDialog.js} +9 -3
  24. package/{esm/LinearPileupDisplay/components/SetMaxHeight.d.ts → dist/LinearPileupDisplay/components/SetMaxHeightDialog.d.ts} +1 -1
  25. package/dist/LinearPileupDisplay/components/{SetMaxHeight.js → SetMaxHeightDialog.js} +7 -3
  26. package/dist/LinearPileupDisplay/components/{SortByTag.d.ts → SortByTagDialog.d.ts} +1 -1
  27. package/dist/LinearPileupDisplay/components/{SortByTag.js → SortByTagDialog.js} +7 -3
  28. package/dist/LinearPileupDisplay/configSchema.js +0 -1
  29. package/dist/LinearPileupDisplay/model.d.ts +58 -46
  30. package/dist/LinearPileupDisplay/model.js +69 -41
  31. package/dist/LinearReadArcsDisplay/components/ReactComponent.js +1 -0
  32. package/dist/LinearReadArcsDisplay/model.d.ts +2 -2
  33. package/dist/LinearReadArcsDisplay/model.js +37 -13
  34. package/dist/LinearReadCloudDisplay/components/ReactComponent.js +4 -1
  35. package/dist/LinearReadCloudDisplay/drawPairChains.js +3 -3
  36. package/dist/LinearReadCloudDisplay/model.d.ts +4 -8
  37. package/dist/LinearReadCloudDisplay/model.js +16 -6
  38. package/dist/LinearSNPCoverageDisplay/components/Tooltip.d.ts +1 -1
  39. package/dist/LinearSNPCoverageDisplay/components/Tooltip.js +1 -1
  40. package/dist/LinearSNPCoverageDisplay/models/model.d.ts +1 -1
  41. package/dist/LinearSNPCoverageDisplay/models/model.js +15 -5
  42. package/dist/MismatchParser/index.js +12 -10
  43. package/dist/PileupRPC/base.d.ts +1 -1
  44. package/dist/PileupRPC/methods/GetGlobalValueForTag.d.ts +1 -1
  45. package/dist/PileupRPC/methods/GetReducedFeatures.d.ts +3 -3
  46. package/dist/PileupRPC/methods/GetVisibleModifications.d.ts +1 -1
  47. package/dist/PileupRenderer/PileupLayoutSession.d.ts +1 -1
  48. package/dist/PileupRenderer/PileupLayoutSession.js +3 -2
  49. package/dist/PileupRenderer/PileupRenderer.d.ts +1 -1
  50. package/dist/PileupRenderer/PileupRenderer.js +16 -13
  51. package/dist/PileupRenderer/colorBy.js +3 -5
  52. package/dist/PileupRenderer/components/PileupRendering.d.ts +1 -1
  53. package/dist/PileupRenderer/components/PileupRendering.js +65 -60
  54. package/dist/PileupRenderer/getAlignmentShapeColor.js +24 -16
  55. package/dist/PileupRenderer/layoutFeature.js +6 -1
  56. package/dist/PileupRenderer/layoutFeatures.js +1 -7
  57. package/dist/PileupRenderer/makeImageData.d.ts +1 -1
  58. package/dist/PileupRenderer/makeImageData.js +1 -0
  59. package/dist/PileupRenderer/renderAlignmentShape.js +1 -1
  60. package/dist/PileupRenderer/renderMismatches.js +1 -1
  61. package/dist/PileupRenderer/renderSoftClipping.js +1 -1
  62. package/dist/PileupRenderer/util.js +3 -5
  63. package/dist/SNPCoverageAdapter/generateCoverageBins.js +4 -10
  64. package/dist/SNPCoverageRenderer/SNPCoverageRenderer.d.ts +2 -2
  65. package/dist/SNPCoverageRenderer/SNPCoverageRenderer.js +2 -5
  66. package/dist/index.js +3 -1
  67. package/dist/shared/BaseDisplayComponent.js +3 -1
  68. package/dist/shared/{FilterByTag.js → FilterByTagDialog.js} +16 -6
  69. package/dist/shared/color.js +2 -2
  70. package/dist/shared/index.d.ts +24 -20
  71. package/dist/shared/index.js +4 -5
  72. package/dist/shared/renderSvg.js +1 -3
  73. package/dist/util.d.ts +1 -1
  74. package/esm/AlignmentsFeatureDetail/AlignmentsFeatureDetail.js +5 -3
  75. package/esm/AlignmentsFeatureDetail/BreakendOptionDialog.js +12 -4
  76. package/esm/AlignmentsFeatureDetail/Formatter.js +6 -2
  77. package/esm/AlignmentsFeatureDetail/SuppAlignmentsLocStrings.js +4 -2
  78. package/esm/AlignmentsFeatureDetail/getSAFeatures.js +4 -4
  79. package/esm/AlignmentsFeatureDetail/launchBreakpointSplitView.js +2 -2
  80. package/esm/BamAdapter/BamAdapter.js +12 -18
  81. package/esm/BamAdapter/BamSlightlyLazyFeature.js +0 -1
  82. package/esm/CramAdapter/CramAdapter.d.ts +1 -1
  83. package/esm/CramAdapter/CramAdapter.js +7 -6
  84. package/esm/CramAdapter/CramTestAdapters.js +8 -2
  85. package/esm/GuessAlignmentsTypes/index.js +2 -2
  86. package/esm/LinearAlignmentsDisplay/components/AlignmentsDisplay.d.ts +2 -2
  87. package/esm/LinearAlignmentsDisplay/models/model.d.ts +13 -20
  88. package/esm/LinearAlignmentsDisplay/models/model.js +13 -3
  89. package/esm/LinearPileupDisplay/SharedLinearPileupDisplayMixin.d.ts +9 -4
  90. package/esm/LinearPileupDisplay/SharedLinearPileupDisplayMixin.js +42 -23
  91. package/esm/LinearPileupDisplay/components/{ColorByModifications.js → ColorByModificationsDialog.js} +3 -1
  92. package/esm/LinearPileupDisplay/components/{ColorByTag.js → ColorByTagDialog.js} +4 -2
  93. package/esm/LinearPileupDisplay/components/GroupByDialog.d.ts +11 -0
  94. package/esm/LinearPileupDisplay/components/GroupByDialog.js +104 -0
  95. package/esm/LinearPileupDisplay/components/LinearPileupDisplayBlurb.js +1 -3
  96. package/esm/LinearPileupDisplay/components/{SetFeatureHeight.js → SetFeatureHeightDialog.js} +9 -3
  97. package/{dist/LinearPileupDisplay/components/SetMaxHeight.d.ts → esm/LinearPileupDisplay/components/SetMaxHeightDialog.d.ts} +1 -1
  98. package/esm/LinearPileupDisplay/components/{SetMaxHeight.js → SetMaxHeightDialog.js} +7 -3
  99. package/esm/LinearPileupDisplay/components/{SortByTag.d.ts → SortByTagDialog.d.ts} +1 -1
  100. package/esm/LinearPileupDisplay/components/{SortByTag.js → SortByTagDialog.js} +7 -3
  101. package/esm/LinearPileupDisplay/configSchema.js +0 -1
  102. package/esm/LinearPileupDisplay/model.d.ts +58 -46
  103. package/esm/LinearPileupDisplay/model.js +69 -41
  104. package/esm/LinearReadArcsDisplay/components/ReactComponent.js +1 -0
  105. package/esm/LinearReadArcsDisplay/model.d.ts +2 -2
  106. package/esm/LinearReadArcsDisplay/model.js +37 -13
  107. package/esm/LinearReadCloudDisplay/components/ReactComponent.js +4 -1
  108. package/esm/LinearReadCloudDisplay/drawPairChains.js +3 -3
  109. package/esm/LinearReadCloudDisplay/model.d.ts +4 -8
  110. package/esm/LinearReadCloudDisplay/model.js +16 -6
  111. package/esm/LinearSNPCoverageDisplay/components/Tooltip.d.ts +1 -1
  112. package/esm/LinearSNPCoverageDisplay/components/Tooltip.js +1 -1
  113. package/esm/LinearSNPCoverageDisplay/models/model.d.ts +1 -1
  114. package/esm/LinearSNPCoverageDisplay/models/model.js +15 -5
  115. package/esm/MismatchParser/index.js +12 -10
  116. package/esm/PileupRPC/base.d.ts +1 -1
  117. package/esm/PileupRPC/methods/GetGlobalValueForTag.d.ts +1 -1
  118. package/esm/PileupRPC/methods/GetReducedFeatures.d.ts +3 -3
  119. package/esm/PileupRPC/methods/GetVisibleModifications.d.ts +1 -1
  120. package/esm/PileupRenderer/PileupLayoutSession.d.ts +1 -1
  121. package/esm/PileupRenderer/PileupLayoutSession.js +3 -2
  122. package/esm/PileupRenderer/PileupRenderer.d.ts +1 -1
  123. package/esm/PileupRenderer/PileupRenderer.js +16 -13
  124. package/esm/PileupRenderer/colorBy.js +3 -5
  125. package/esm/PileupRenderer/components/PileupRendering.d.ts +1 -1
  126. package/esm/PileupRenderer/components/PileupRendering.js +65 -60
  127. package/esm/PileupRenderer/getAlignmentShapeColor.js +24 -16
  128. package/esm/PileupRenderer/layoutFeature.js +6 -1
  129. package/esm/PileupRenderer/layoutFeatures.js +1 -7
  130. package/esm/PileupRenderer/makeImageData.d.ts +1 -1
  131. package/esm/PileupRenderer/makeImageData.js +1 -0
  132. package/esm/PileupRenderer/renderAlignmentShape.js +1 -1
  133. package/esm/PileupRenderer/renderMismatches.js +1 -1
  134. package/esm/PileupRenderer/renderSoftClipping.js +1 -1
  135. package/esm/PileupRenderer/util.js +3 -5
  136. package/esm/SNPCoverageAdapter/generateCoverageBins.js +4 -10
  137. package/esm/SNPCoverageRenderer/SNPCoverageRenderer.d.ts +2 -2
  138. package/esm/SNPCoverageRenderer/SNPCoverageRenderer.js +2 -5
  139. package/esm/index.js +3 -1
  140. package/esm/shared/BaseDisplayComponent.js +3 -1
  141. package/esm/shared/{FilterByTag.js → FilterByTagDialog.js} +16 -6
  142. package/esm/shared/color.js +2 -2
  143. package/esm/shared/index.d.ts +24 -20
  144. package/esm/shared/index.js +4 -5
  145. package/esm/shared/renderSvg.js +1 -3
  146. package/esm/util.d.ts +1 -1
  147. package/package.json +6 -6
  148. /package/dist/LinearPileupDisplay/components/{ColorByModifications.d.ts → ColorByModificationsDialog.d.ts} +0 -0
  149. /package/dist/LinearPileupDisplay/components/{ColorByTag.d.ts → ColorByTagDialog.d.ts} +0 -0
  150. /package/dist/LinearPileupDisplay/components/{SetFeatureHeight.d.ts → SetFeatureHeightDialog.d.ts} +0 -0
  151. /package/dist/shared/{FilterByTag.d.ts → FilterByTagDialog.d.ts} +0 -0
  152. /package/esm/LinearPileupDisplay/components/{ColorByModifications.d.ts → ColorByModificationsDialog.d.ts} +0 -0
  153. /package/esm/LinearPileupDisplay/components/{ColorByTag.d.ts → ColorByTagDialog.d.ts} +0 -0
  154. /package/esm/LinearPileupDisplay/components/{SetFeatureHeight.d.ts → SetFeatureHeightDialog.d.ts} +0 -0
  155. /package/esm/shared/{FilterByTag.d.ts → FilterByTagDialog.d.ts} +0 -0
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ import { IAnyStateTreeNode } from 'mobx-state-tree';
3
+ import { AnyConfigurationModel } from '@jbrowse/core/configuration';
4
+ declare const GroupByTagDialog: (props: {
5
+ model: {
6
+ adapterConfig: AnyConfigurationModel;
7
+ configuration: AnyConfigurationModel;
8
+ } & IAnyStateTreeNode;
9
+ handleClose: () => void;
10
+ }) => React.JSX.Element;
11
+ export default GroupByTagDialog;
@@ -0,0 +1,104 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import { observer } from 'mobx-react';
3
+ import { Button, Checkbox, DialogActions, DialogContent, FormControlLabel, TextField, Typography, } from '@mui/material';
4
+ import { Dialog, ErrorMessage, LoadingEllipses } from '@jbrowse/core/ui';
5
+ import { getSnapshot } from 'mobx-state-tree';
6
+ import { getContainingTrack, getContainingView, getSession, useDebounce, } from '@jbrowse/core/util';
7
+ // locals
8
+ import { getUniqueTagValues } from '../../shared';
9
+ function clone(c) {
10
+ return JSON.parse(JSON.stringify(c));
11
+ }
12
+ const GroupByTagDialog = observer(function (props) {
13
+ const { model, handleClose } = props;
14
+ const [tag, setTag] = useState('');
15
+ const [tagSet, setTagSet] = useState();
16
+ const [loading, setLoading] = useState(false);
17
+ const [error, setError] = useState();
18
+ const [includeUndefined, setIncludeUndefined] = useState(true);
19
+ const validTag = /^[A-Za-z][A-Za-z0-9]$/.exec(tag);
20
+ const isInvalid = tag.length === 2 && !validTag;
21
+ const debouncedTag = useDebounce(tag, 1000);
22
+ useEffect(() => {
23
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
24
+ ;
25
+ (async () => {
26
+ try {
27
+ if (!isInvalid) {
28
+ setError(undefined);
29
+ setLoading(true);
30
+ const vals = await getUniqueTagValues({
31
+ self: model,
32
+ tag: debouncedTag,
33
+ blocks: getContainingView(model)
34
+ .staticBlocks,
35
+ });
36
+ setTagSet(vals);
37
+ }
38
+ }
39
+ catch (e) {
40
+ console.error(e);
41
+ setError(e);
42
+ }
43
+ finally {
44
+ setLoading(false);
45
+ }
46
+ })();
47
+ }, [model, isInvalid, debouncedTag]);
48
+ return (React.createElement(Dialog, { open: true, onClose: handleClose, title: "Group by tag" },
49
+ React.createElement(DialogContent, null,
50
+ React.createElement(Typography, null, "Set the tag to group by. NOTE: this will make a set of fully functional subtracks with the filter by by default set to the values of the tag that are visible in the current view"),
51
+ React.createElement(Typography, { color: "textSecondary" }, "Examples: HP for haplotype, RG for read group, etc."),
52
+ React.createElement(FormControlLabel, { control: React.createElement(Checkbox, { checked: includeUndefined, onChange: () => {
53
+ setIncludeUndefined(!includeUndefined);
54
+ } }), label: "Make a new subtrack for undefined values of tag as well?" }),
55
+ React.createElement(TextField, { value: tag, onChange: event => {
56
+ setTag(event.target.value);
57
+ }, placeholder: "Enter tag name", inputProps: {
58
+ maxLength: 2,
59
+ 'data-testid': 'group-tag-name-input',
60
+ }, error: isInvalid, helperText: isInvalid ? 'Not a valid tag' : '', autoComplete: "off", "data-testid": "group-tag-name" }),
61
+ error ? (React.createElement(ErrorMessage, { error: error })) : loading ? (React.createElement(LoadingEllipses, { title: "Loading unique tags" })) : tagSet ? (React.createElement("div", null,
62
+ React.createElement("div", null,
63
+ "Found unique ",
64
+ tag,
65
+ " values:"),
66
+ React.createElement("div", null, tagSet.join(', ')))) : null),
67
+ React.createElement(DialogActions, null,
68
+ React.createElement(Button, { variant: "contained", color: "primary", type: "submit", disabled: !tagSet, autoFocus: true, onClick: () => {
69
+ const track = getContainingTrack(model);
70
+ const trackConf = clone(getSnapshot(track.configuration));
71
+ const session = getSession(model);
72
+ if (tagSet) {
73
+ const ret = [...tagSet];
74
+ if (includeUndefined) {
75
+ ret.push(undefined);
76
+ }
77
+ for (const tagValue of ret) {
78
+ // @ts-expect-error
79
+ const newTrackConf = session.addTrackConf({
80
+ ...trackConf,
81
+ trackId: `${trackConf.trackId}-${tag}:${tagValue}-${+Date.now()}-sessionTrack`,
82
+ name: `${trackConf.name} ${tag}:${tagValue}`,
83
+ displays: undefined,
84
+ });
85
+ const view = getContainingView(model);
86
+ const t = view.showTrack(newTrackConf.trackId);
87
+ const d = t.displays[0];
88
+ d.setFilterBy({
89
+ flagInclude: 0,
90
+ flagExclude: 1540,
91
+ tagFilter: {
92
+ tag,
93
+ value: tagValue,
94
+ },
95
+ });
96
+ }
97
+ }
98
+ handleClose();
99
+ } }, "Submit"),
100
+ React.createElement(Button, { variant: "contained", color: "secondary", onClick: () => {
101
+ handleClose();
102
+ } }, "Cancel"))));
103
+ });
104
+ export default GroupByTagDialog;
@@ -5,8 +5,6 @@ const LinearPileupDisplayBlurb = observer(function ({ model, }) {
5
5
  var _a;
6
6
  const { sortedBy } = model;
7
7
  return sortedBy ? (React.createElement("div", { "data-testid": `blurb-${sortedBy}` },
8
- React.createElement(Typography, { color: "secondary", variant: "caption" }, sortedBy
9
- ? `Sorted by ${(_a = sortedBy.tag) !== null && _a !== void 0 ? _a : sortedBy.type} at ${sortedBy.refName}:${sortedBy.pos}`
10
- : null))) : null;
8
+ React.createElement(Typography, { color: "secondary", variant: "caption" }, `Sorted by ${(_a = sortedBy.tag) !== null && _a !== void 0 ? _a : sortedBy.type} at ${sortedBy.refName}:${sortedBy.pos}`))) : null;
11
9
  });
12
10
  export default LinearPileupDisplayBlurb;
@@ -11,14 +11,20 @@ const SetFeatureHeightDialog = observer(function (props) {
11
11
  return (React.createElement(Dialog, { open: true, onClose: handleClose, title: "Set feature height" },
12
12
  React.createElement(DialogContent, null,
13
13
  React.createElement(Typography, null, "Adjust the feature height and whether there is any spacing between features. Setting feature height to 1 and removing spacing makes the display very compact."),
14
- React.createElement(TextField, { value: height, helperText: "Feature height", onChange: event => setHeight(event.target.value) }),
15
- React.createElement(FormControlLabel, { control: React.createElement(Checkbox, { checked: !!noSpacing, onChange: () => setNoSpacing(val => !val) }), label: "Remove spacing between features in y-direction?" }),
14
+ React.createElement(TextField, { value: height, helperText: "Feature height", onChange: event => {
15
+ setHeight(event.target.value);
16
+ } }),
17
+ React.createElement(FormControlLabel, { control: React.createElement(Checkbox, { checked: !!noSpacing, onChange: () => {
18
+ setNoSpacing(val => !val);
19
+ } }), label: "Remove spacing between features in y-direction?" }),
16
20
  React.createElement(DialogActions, null,
17
21
  React.createElement(Button, { variant: "contained", color: "primary", type: "submit", autoFocus: true, disabled: !ok, onClick: () => {
18
22
  model.setFeatureHeight(height !== '' && !Number.isNaN(+height) ? +height : undefined);
19
23
  model.setNoSpacing(noSpacing);
20
24
  handleClose();
21
25
  } }, "Submit"),
22
- React.createElement(Button, { variant: "contained", color: "secondary", onClick: () => handleClose() }, "Cancel")))));
26
+ React.createElement(Button, { variant: "contained", color: "secondary", onClick: () => {
27
+ handleClose();
28
+ } }, "Cancel")))));
23
29
  });
24
30
  export default SetFeatureHeightDialog;
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  declare const SetMaxHeightDialog: (props: {
3
3
  model: {
4
4
  maxHeight?: number;
5
- setMaxHeight: Function;
5
+ setMaxHeight: (arg?: number) => void;
6
6
  };
7
7
  handleClose: () => void;
8
8
  }) => React.JSX.Element;
@@ -13,15 +13,19 @@ const SetMaxHeightDialog = observer(function (props) {
13
13
  const { classes } = useStyles();
14
14
  const { maxHeight = '' } = model;
15
15
  const [max, setMax] = useState(`${maxHeight}`);
16
- return (React.createElement(Dialog, { open: true, onClose: handleClose, title: "Filter options" },
16
+ return (React.createElement(Dialog, { open: true, onClose: handleClose, title: "Set max height" },
17
17
  React.createElement(DialogContent, { className: classes.root },
18
18
  React.createElement(Typography, null, "Set max height for the track. For example, you can increase this if the layout says \"Max height reached\""),
19
- React.createElement(TextField, { value: max, onChange: event => setMax(event.target.value), placeholder: "Enter max height for layout" }),
19
+ React.createElement(TextField, { value: max, autoFocus: true, onChange: event => {
20
+ setMax(event.target.value);
21
+ }, placeholder: "Enter max height for layout" }),
20
22
  React.createElement(DialogActions, null,
21
23
  React.createElement(Button, { variant: "contained", color: "primary", type: "submit", autoFocus: true, onClick: () => {
22
24
  model.setMaxHeight(max !== '' && !Number.isNaN(+max) ? +max : undefined);
23
25
  handleClose();
24
26
  } }, "Submit"),
25
- React.createElement(Button, { variant: "contained", color: "secondary", onClick: () => handleClose() }, "Cancel")))));
27
+ React.createElement(Button, { variant: "contained", color: "secondary", onClick: () => {
28
+ handleClose();
29
+ } }, "Cancel")))));
26
30
  });
27
31
  export default SetMaxHeightDialog;
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  declare const SortByTagDialog: (props: {
3
3
  model: {
4
- setSortedBy: Function;
4
+ setSortedBy: (arg: string, arg2: string) => void;
5
5
  };
6
6
  handleClose: () => void;
7
7
  }) => React.JSX.Element;
@@ -5,12 +5,14 @@ import { Dialog } from '@jbrowse/core/ui';
5
5
  const SortByTagDialog = observer(function (props) {
6
6
  const { model, handleClose } = props;
7
7
  const [tag, setTag] = useState('');
8
- const validTag = tag.match(/^[A-Za-z][A-Za-z0-9]$/);
8
+ const validTag = /^[A-Za-z][A-Za-z0-9]$/.exec(tag);
9
9
  return (React.createElement(Dialog, { open: true, onClose: handleClose, title: "Sort by tag" },
10
10
  React.createElement(DialogContent, null,
11
11
  React.createElement(Typography, null, "Set the tag to sort by"),
12
12
  React.createElement(Typography, { color: "textSecondary" }, "Examples: HP for haplotype, RG for read group, etc."),
13
- React.createElement(TextField, { value: tag, onChange: event => setTag(event.target.value), placeholder: "Enter tag name", inputProps: {
13
+ React.createElement(TextField, { value: tag, onChange: event => {
14
+ setTag(event.target.value);
15
+ }, placeholder: "Enter tag name", inputProps: {
14
16
  maxLength: 2,
15
17
  'data-testid': 'sort-tag-name-input',
16
18
  }, error: tag.length === 2 && !validTag, helperText: tag.length === 2 && !validTag ? 'Not a valid tag' : '', autoComplete: "off", "data-testid": "sort-tag-name" }),
@@ -19,6 +21,8 @@ const SortByTagDialog = observer(function (props) {
19
21
  model.setSortedBy('tag', tag);
20
22
  handleClose();
21
23
  } }, "Submit"),
22
- React.createElement(Button, { variant: "contained", color: "secondary", onClick: () => handleClose() }, "Cancel")))));
24
+ React.createElement(Button, { variant: "contained", color: "secondary", onClick: () => {
25
+ handleClose();
26
+ } }, "Cancel")))));
23
27
  });
24
28
  export default SortByTagDialog;
@@ -6,7 +6,6 @@ import { types } from 'mobx-state-tree';
6
6
  */
7
7
  function x() { } // eslint-disable-line @typescript-eslint/no-unused-vars
8
8
  function configSchemaF(pluginManager) {
9
- // modify config schema to take in a sub coverage display
10
9
  return ConfigurationSchema('LinearPileupDisplay', {
11
10
  /**
12
11
  * #slot
@@ -116,7 +116,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
116
116
  readName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
117
117
  tagFilter: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IModelType<{
118
118
  tag: import("mobx-state-tree").ISimpleType<string>;
119
- value: import("mobx-state-tree").ISimpleType<string>;
119
+ value: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
120
120
  }, {}, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
121
121
  }, {}, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>, [undefined]>;
122
122
  jexlFilters: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").IArrayType<import("mobx-state-tree").ISimpleType<string>>, [undefined]>;
@@ -154,8 +154,10 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
154
154
  rendererTypeName: string;
155
155
  error: unknown;
156
156
  message: string | undefined;
157
- }, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
158
- onHorizontalScroll?: Function;
157
+ }, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree" /**
158
+ * #property
159
+ */)._NotCustomized>>;
160
+ onHorizontalScroll?: () => void;
159
161
  blockState?: Record<string, any>;
160
162
  }>;
161
163
  readonly DisplayBlurb: import("react").FC<{
@@ -175,9 +177,9 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
175
177
  rendererTypeName: string;
176
178
  error: unknown;
177
179
  message: string | undefined;
178
- }, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree" /**
180
+ }, import("mobx-state-tree" /**
179
181
  * #action
180
- */)._NotCustomized>>;
182
+ */)._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
181
183
  }> | null;
182
184
  readonly adapterConfig: any;
183
185
  readonly parentTrack: any;
@@ -267,7 +269,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
267
269
  readonly autorunReady: boolean;
268
270
  } & {
269
271
  setTagsReady(flag: boolean): void;
270
- setMaxHeight(n: number): void;
272
+ setMaxHeight(n?: number): void;
271
273
  setFeatureHeight(n?: number): void;
272
274
  setNoSpacing(flag?: boolean): void;
273
275
  setColorScheme(colorScheme: {
@@ -292,9 +294,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
292
294
  setSubschema(slotName: string, data: Record<string, unknown>): Record<string, unknown> | ({
293
295
  [x: string]: any;
294
296
  } & import("mobx-state-tree/dist/internal").NonEmptyObject & any & import("mobx-state-tree").IStateTreeNode<AnyConfigurationSchemaType>);
295
- } & import("mobx-state-tree" /**
296
- * #property
297
- */).IStateTreeNode<AnyConfigurationSchemaType>);
297
+ } & import("mobx-state-tree").IStateTreeNode<AnyConfigurationSchemaType>);
298
298
  } & import("mobx-state-tree").IStateTreeNode<AnyConfigurationSchemaType>;
299
299
  } & {
300
300
  readonly maxHeight: any;
@@ -335,6 +335,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
335
335
  icon: import("@mui/material/OverridableComponent").OverridableComponent<import("@mui/material").SvgIconTypeMap<{}, "svg">> & {
336
336
  muiName: string;
337
337
  };
338
+ priority: number;
338
339
  onClick: () => void;
339
340
  })[];
340
341
  } & {
@@ -426,49 +427,60 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
426
427
  /**
427
428
  * #method
428
429
  */
429
- trackMenuItems(): (import("@jbrowse/core/ui").MenuDivider | import("@jbrowse/core/ui").MenuSubHeader | import("@jbrowse/core/ui").NormalMenuItem | import("@jbrowse/core/ui").CheckboxMenuItem | import("@jbrowse/core/ui").RadioMenuItem | import("@jbrowse/core/ui").SubMenuItem | {
430
- label: string;
431
- icon: import("@mui/material/OverridableComponent").OverridableComponent<import("@mui/material").SvgIconTypeMap<{}, "svg">> & {
430
+ trackMenuItems(): readonly [...import("@jbrowse/core/ui").MenuItem[], {
431
+ readonly label: "Color by...";
432
+ readonly icon: import("@mui/material/OverridableComponent").OverridableComponent<import("@mui/material").SvgIconTypeMap<{}, "svg">> & {
432
433
  muiName: string;
433
434
  };
434
- type: string;
435
- checked: boolean;
436
- onClick: () => void;
437
- disabled?: undefined;
438
- subMenu?: undefined;
439
- } | {
440
- label: string;
441
- icon: import("@mui/material/OverridableComponent").OverridableComponent<import("@mui/material").SvgIconTypeMap<{}, "svg">> & {
442
- muiName: string;
443
- };
444
- disabled: boolean;
445
- subMenu: {
435
+ readonly subMenu: readonly [{
436
+ readonly label: "Pair orientation";
437
+ readonly onClick: () => void;
438
+ }, {
439
+ readonly label: "Modifications or methylation";
440
+ readonly onClick: () => void;
441
+ }, {
442
+ readonly label: "Insert size";
443
+ readonly onClick: () => void;
444
+ }, ...{
446
445
  label: string;
447
446
  onClick: () => void;
448
- }[];
449
- type?: undefined;
450
- checked?: undefined;
451
- onClick?: undefined;
452
- } | {
453
- label: string;
454
- subMenu: {
447
+ }[]];
448
+ }, {
449
+ readonly label: "Sort by...";
450
+ readonly icon: import("@mui/material/OverridableComponent").OverridableComponent<import("@mui/material").SvgIconTypeMap<{}, "svg">> & {
451
+ muiName: string;
452
+ };
453
+ readonly disabled: boolean;
454
+ readonly subMenu: readonly [...{
455
455
  label: string;
456
456
  onClick: () => void;
457
- }[];
458
- icon?: undefined;
459
- type?: undefined;
460
- checked?: undefined;
461
- onClick?: undefined;
462
- disabled?: undefined;
463
- } | {
464
- label: string;
465
- type: string;
466
- checked: any;
467
- onClick: () => void;
468
- icon?: undefined;
469
- disabled?: undefined;
470
- subMenu?: undefined;
471
- })[];
457
+ }[], {
458
+ readonly label: "Sort by tag...";
459
+ readonly onClick: () => void;
460
+ }, {
461
+ readonly label: "Clear sort";
462
+ readonly onClick: () => void;
463
+ }];
464
+ }, {
465
+ readonly label: "Group by...";
466
+ readonly icon: import("@mui/material/OverridableComponent").OverridableComponent<import("@mui/material").SvgIconTypeMap<{}, "svg">> & {
467
+ muiName: string;
468
+ };
469
+ readonly onClick: () => void;
470
+ }, {
471
+ readonly label: "Show soft clipping";
472
+ readonly icon: import("@mui/material/OverridableComponent").OverridableComponent<import("@mui/material").SvgIconTypeMap<{}, "svg">> & {
473
+ muiName: string;
474
+ };
475
+ readonly type: "checkbox";
476
+ readonly checked: boolean;
477
+ readonly onClick: () => void;
478
+ }, {
479
+ readonly label: "Fade mismatches by quality";
480
+ readonly type: "checkbox";
481
+ readonly checked: any;
482
+ readonly onClick: () => void;
483
+ }];
472
484
  } & {
473
485
  afterAttach(): void;
474
486
  }, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>;
@@ -8,12 +8,15 @@ import { createAutorun, randomColor, modificationColors } from '../util';
8
8
  // icons
9
9
  import VisibilityIcon from '@mui/icons-material/Visibility';
10
10
  import SortIcon from '@mui/icons-material/Sort';
11
+ import WorkspacesIcon from '@mui/icons-material/Workspaces';
12
+ import ColorLensIcon from '@mui/icons-material/ColorLens';
11
13
  // locals
12
14
  import { SharedLinearPileupDisplayMixin } from './SharedLinearPileupDisplayMixin';
13
15
  import { observable } from 'mobx';
14
- // lzies
15
- const SortByTagDialog = lazy(() => import('./components/SortByTag'));
16
- const ModificationsDialog = lazy(() => import('./components/ColorByModifications'));
16
+ // lazies
17
+ const SortByTagDialog = lazy(() => import('./components/SortByTagDialog'));
18
+ const GroupByDialog = lazy(() => import('./components/GroupByDialog'));
19
+ const ModificationsDialog = lazy(() => import('./components/ColorByModificationsDialog'));
17
20
  /**
18
21
  * #stateModel LinearPileupDisplay
19
22
  * #category display
@@ -220,27 +223,43 @@ function stateModelFactory(configSchema) {
220
223
  return [
221
224
  ...superTrackMenuItems(),
222
225
  {
223
- label: 'Show soft clipping',
224
- icon: VisibilityIcon,
225
- type: 'checkbox',
226
- checked: self.showSoftClipping,
227
- onClick: () => {
228
- self.toggleSoftClipping();
229
- // if toggling from off to on, will break sort for this track
230
- // so clear it
231
- if (self.showSoftClipping) {
232
- self.clearSelected();
233
- }
234
- },
226
+ label: 'Color by...',
227
+ icon: ColorLensIcon,
228
+ subMenu: [
229
+ {
230
+ label: 'Pair orientation',
231
+ onClick: () => {
232
+ self.setColorScheme({ type: 'pairOrientation' });
233
+ },
234
+ },
235
+ {
236
+ label: 'Modifications or methylation',
237
+ onClick: () => {
238
+ getSession(self).queueDialog(doneCallback => [
239
+ ModificationsDialog,
240
+ { model: self, handleClose: doneCallback },
241
+ ]);
242
+ },
243
+ },
244
+ {
245
+ label: 'Insert size',
246
+ onClick: () => {
247
+ self.setColorScheme({ type: 'insertSize' });
248
+ },
249
+ },
250
+ ...superColorSchemeSubMenuItems(),
251
+ ],
235
252
  },
236
253
  {
237
- label: 'Sort by',
254
+ label: 'Sort by...',
238
255
  icon: SortIcon,
239
256
  disabled: self.showSoftClipping,
240
257
  subMenu: [
241
258
  ...['Start location', 'Read strand', 'Base pair'].map(option => ({
242
259
  label: option,
243
- onClick: () => self.setSortedBy(option),
260
+ onClick: () => {
261
+ self.setSortedBy(option);
262
+ },
244
263
  })),
245
264
  {
246
265
  label: 'Sort by tag...',
@@ -253,38 +272,43 @@ function stateModelFactory(configSchema) {
253
272
  },
254
273
  {
255
274
  label: 'Clear sort',
256
- onClick: () => self.clearSelected(),
257
- },
258
- ],
259
- },
260
- {
261
- label: 'Color scheme',
262
- subMenu: [
263
- {
264
- label: 'Pair orientation',
265
- onClick: () => self.setColorScheme({ type: 'pairOrientation' }),
266
- },
267
- {
268
- label: 'Modifications or methylation',
269
275
  onClick: () => {
270
- getSession(self).queueDialog(doneCallback => [
271
- ModificationsDialog,
272
- { model: self, handleClose: doneCallback },
273
- ]);
276
+ self.clearSelected();
274
277
  },
275
278
  },
276
- {
277
- label: 'Insert size',
278
- onClick: () => self.setColorScheme({ type: 'insertSize' }),
279
- },
280
- ...superColorSchemeSubMenuItems(),
281
279
  ],
282
280
  },
281
+ {
282
+ label: 'Group by...',
283
+ icon: WorkspacesIcon,
284
+ onClick: () => {
285
+ getSession(self).queueDialog(handleClose => [
286
+ GroupByDialog,
287
+ { model: self, handleClose },
288
+ ]);
289
+ },
290
+ },
291
+ {
292
+ label: 'Show soft clipping',
293
+ icon: VisibilityIcon,
294
+ type: 'checkbox',
295
+ checked: self.showSoftClipping,
296
+ onClick: () => {
297
+ self.toggleSoftClipping();
298
+ // if toggling from off to on, will break sort for this track
299
+ // so clear it
300
+ if (self.showSoftClipping) {
301
+ self.clearSelected();
302
+ }
303
+ },
304
+ },
283
305
  {
284
306
  label: 'Fade mismatches by quality',
285
307
  type: 'checkbox',
286
308
  checked: self.mismatchAlphaSetting,
287
- onClick: () => self.toggleMismatchAlpha(),
309
+ onClick: () => {
310
+ self.toggleMismatchAlpha();
311
+ },
288
312
  },
289
313
  ];
290
314
  },
@@ -342,7 +366,11 @@ function stateModelFactory(configSchema) {
342
366
  const { staticBlocks } = getContainingView(self);
343
367
  if ((colorBy === null || colorBy === void 0 ? void 0 : colorBy.type) === 'modifications') {
344
368
  const adapter = getConf(parentTrack, ['adapter']);
345
- const vals = await getUniqueModificationValues(self, adapter, colorBy, staticBlocks);
369
+ const vals = await getUniqueModificationValues({
370
+ self,
371
+ adapterConfig: adapter,
372
+ blocks: staticBlocks,
373
+ });
346
374
  self.updateModificationColorMap(vals);
347
375
  }
348
376
  self.setModificationsReady(true);
@@ -6,6 +6,7 @@ const Arcs = observer(function ({ model, }) {
6
6
  const view = getContainingView(model);
7
7
  const width = Math.round(view.dynamicBlocks.totalWidthPx);
8
8
  const height = model.height;
9
+ // biome-ignore lint/correctness/useExhaustiveDependencies:
9
10
  const cb = useCallback((ref) => {
10
11
  model.setRef(ref);
11
12
  },
@@ -30,7 +30,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
30
30
  readName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
31
31
  tagFilter: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IModelType<{
32
32
  tag: import("mobx-state-tree").ISimpleType<string>;
33
- value: import("mobx-state-tree").ISimpleType<string>;
33
+ value: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
34
34
  }, {}, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
35
35
  }, {}, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>, [undefined]>;
36
36
  lineWidth: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<number>>;
@@ -65,7 +65,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
65
65
  error: unknown;
66
66
  message: string | undefined;
67
67
  }, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
68
- onHorizontalScroll?: Function;
68
+ onHorizontalScroll?: () => void;
69
69
  blockState?: Record<string, any>;
70
70
  }>;
71
71
  readonly DisplayBlurb: React.FC<{