@jbrowse/core 2.11.0 → 2.11.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.
- package/BaseFeatureWidget/BaseFeatureDetail/DataGridDetails.js +2 -6
- package/BaseFeatureWidget/BaseFeatureDetail/index.js +10 -2
- package/BaseFeatureWidget/SequenceFeatureDetails/SequenceFeatureDetails.d.ts +7 -2
- package/BaseFeatureWidget/SequenceFeatureDetails/SequenceFeatureDetails.js +80 -86
- package/BaseFeatureWidget/SequenceFeatureDetails/SequenceFeaturePanel.d.ts +8 -0
- package/BaseFeatureWidget/SequenceFeatureDetails/SequenceFeaturePanel.js +67 -0
- package/BaseFeatureWidget/SequenceFeatureDetails/SequencePanel.d.ts +5 -3
- package/BaseFeatureWidget/SequenceFeatureDetails/SequencePanel.js +7 -7
- package/BaseFeatureWidget/SequenceFeatureDetails/dialogs/SettingsDialog.d.ts +7 -0
- package/BaseFeatureWidget/SequenceFeatureDetails/{SequenceFeatureSettingsDialog.js → dialogs/SettingsDialog.js} +20 -10
- package/BaseFeatureWidget/SequenceFeatureDetails/hooks.js +2 -8
- package/BaseFeatureWidget/SequenceFeatureDetails/index.d.ts +1 -3
- package/BaseFeatureWidget/SequenceFeatureDetails/index.js +3 -67
- package/BaseFeatureWidget/SequenceFeatureDetails/model.d.ts +14 -0
- package/BaseFeatureWidget/SequenceFeatureDetails/model.js +40 -0
- package/BaseFeatureWidget/SequenceFeatureDetails/seqtypes/CDNASequence.d.ts +15 -0
- package/BaseFeatureWidget/SequenceFeatureDetails/{CDNASequence.js → seqtypes/CDNASequence.js} +17 -8
- package/BaseFeatureWidget/SequenceFeatureDetails/{CDSSequence.d.ts → seqtypes/CDSSequence.d.ts} +1 -1
- package/BaseFeatureWidget/SequenceFeatureDetails/{CDSSequence.js → seqtypes/CDSSequence.js} +2 -2
- package/BaseFeatureWidget/SequenceFeatureDetails/{GenomicSequence.js → seqtypes/GenomicSequence.js} +1 -1
- package/BaseFeatureWidget/SequenceFeatureDetails/{ProteinSequence.d.ts → seqtypes/ProteinSequence.d.ts} +1 -1
- package/BaseFeatureWidget/SequenceFeatureDetails/{ProteinSequence.js → seqtypes/ProteinSequence.js} +2 -2
- package/BaseFeatureWidget/stateModelFactory.d.ts +32 -0
- package/BaseFeatureWidget/stateModelFactory.js +5 -0
- package/BaseFeatureWidget/types.d.ts +2 -7
- package/BaseFeatureWidget/util.d.ts +4 -2
- package/PluginManager.d.ts +1 -1
- package/ReExports/modules.d.ts +1 -1
- package/configuration/util.js +4 -11
- package/data_adapters/CytobandAdapter/index.d.ts +1 -2
- package/data_adapters/CytobandAdapter/index.js +3 -2
- package/package.json +3 -3
- package/pluggableElementTypes/models/BaseDisplayModel.d.ts +3 -3
- package/pluggableElementTypes/models/BaseDisplayModel.js +3 -3
- package/pluggableElementTypes/renderers/util/serializableFilterChain.js +4 -1
- package/rpc/methods/util.d.ts +3 -2
- package/rpc/methods/util.js +0 -7
- package/tsconfig.build.tsbuildinfo +1 -1
- package/ui/ErrorMessageStackTraceDialog.js +13 -8
- package/ui/index.d.ts +0 -1
- package/ui/index.js +1 -3
- package/util/blockTypes.d.ts +4 -0
- package/util/blockTypes.js +14 -3
- package/util/calculateDynamicBlocks.js +2 -3
- package/util/index.d.ts +8 -0
- package/util/index.js +12 -2
- package/util/jexl.d.ts +1 -1
- package/util/jexl.js +2 -2
- package/util/range.d.ts +1 -1
- package/util/simpleFeature.d.ts +4 -0
- package/BaseFeatureWidget/SequenceFeatureDetails/CDNASequence.d.ts +0 -13
- package/BaseFeatureWidget/SequenceFeatureDetails/SequenceFeatureSettingsDialog.d.ts +0 -9
- package/ui/ResizeBar.d.ts +0 -7
- package/ui/ResizeBar.js +0 -80
- package/ui/Tooltip.d.ts +0 -11
- package/ui/Tooltip.js +0 -54
- /package/BaseFeatureWidget/SequenceFeatureDetails/{SequenceHelpDialog.d.ts → dialogs/HelpDialog.d.ts} +0 -0
- /package/BaseFeatureWidget/SequenceFeatureDetails/{SequenceHelpDialog.js → dialogs/HelpDialog.js} +0 -0
- /package/BaseFeatureWidget/SequenceFeatureDetails/{GenomicSequence.d.ts → seqtypes/GenomicSequence.d.ts} +0 -0
|
@@ -32,9 +32,7 @@ const x_data_grid_1 = require("@mui/x-data-grid");
|
|
|
32
32
|
const material_1 = require("@mui/material");
|
|
33
33
|
// locals
|
|
34
34
|
const util_1 = require("../../util");
|
|
35
|
-
const ResizeBar_1 = __importDefault(require("../../ui/ResizeBar"));
|
|
36
35
|
const FieldName_1 = __importDefault(require("./FieldName"));
|
|
37
|
-
const useResizeBar_1 = require("../../ui/useResizeBar");
|
|
38
36
|
const ui_1 = require("../../ui");
|
|
39
37
|
const useStyles = (0, mui_1.makeStyles)()(theme => ({
|
|
40
38
|
margin: {
|
|
@@ -49,7 +47,6 @@ const useStyles = (0, mui_1.makeStyles)()(theme => ({
|
|
|
49
47
|
}));
|
|
50
48
|
function DataGridDetails({ value, prefix, name, }) {
|
|
51
49
|
const { classes } = useStyles();
|
|
52
|
-
const { ref, scrollLeft } = (0, useResizeBar_1.useResizeBar)();
|
|
53
50
|
const [checked, setChecked] = (0, react_1.useState)(false);
|
|
54
51
|
const keys = Object.keys(value[0]).sort();
|
|
55
52
|
const unionKeys = new Set(keys);
|
|
@@ -77,13 +74,12 @@ function DataGridDetails({ value, prefix, name, }) {
|
|
|
77
74
|
else {
|
|
78
75
|
colNames = [...unionKeys];
|
|
79
76
|
}
|
|
80
|
-
const
|
|
77
|
+
const widths = colNames.map(e => (0, util_1.measureGridWidth)(rows.map(r => r[e])));
|
|
81
78
|
if (unionKeys.size < keys.length + 5) {
|
|
82
79
|
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
83
80
|
react_1.default.createElement(FieldName_1.default, { prefix: prefix, name: name }),
|
|
84
81
|
react_1.default.createElement(material_1.FormControlLabel, { control: react_1.default.createElement(material_1.Checkbox, { checked: checked, onChange: event => setChecked(event.target.checked) }), label: react_1.default.createElement(material_1.Typography, { variant: "body2" }, "Show options") }),
|
|
85
|
-
react_1.default.createElement("div", { className: classes.margin
|
|
86
|
-
react_1.default.createElement(ResizeBar_1.default, { widths: widths, setWidths: setWidths, scrollLeft: scrollLeft }),
|
|
82
|
+
react_1.default.createElement("div", { className: classes.margin },
|
|
87
83
|
react_1.default.createElement(x_data_grid_1.DataGrid, { disableRowSelectionOnClick: true,
|
|
88
84
|
// @ts-expect-error the rows gets confused by the renderCell of the
|
|
89
85
|
// columns below
|
|
@@ -84,7 +84,6 @@ function Position(props) {
|
|
|
84
84
|
'1': '+',
|
|
85
85
|
};
|
|
86
86
|
const str = strandMap[strand] ? `(${strandMap[strand]})` : '';
|
|
87
|
-
// @ts-expect-error
|
|
88
87
|
const loc = (0, util_1.assembleLocString)(feature);
|
|
89
88
|
return react_1.default.createElement(react_1.default.Fragment, null, `${loc} ${str}`);
|
|
90
89
|
}
|
|
@@ -140,7 +139,16 @@ function FeatureDetails(props) {
|
|
|
140
139
|
mate ? (react_1.default.createElement(react_1.default.Fragment, null,
|
|
141
140
|
react_1.default.createElement(material_1.Divider, null),
|
|
142
141
|
react_1.default.createElement(material_1.Typography, null, "Mate details"),
|
|
143
|
-
react_1.default.createElement(CoreDetails, { ...props, feature: {
|
|
142
|
+
react_1.default.createElement(CoreDetails, { ...props, feature: {
|
|
143
|
+
...mate,
|
|
144
|
+
// @ts-expect-error
|
|
145
|
+
start: mate.start,
|
|
146
|
+
// @ts-expect-error
|
|
147
|
+
end: mate.end,
|
|
148
|
+
// @ts-expect-error
|
|
149
|
+
refName: mate.refName,
|
|
150
|
+
uniqueId: uniqueId + '-mate',
|
|
151
|
+
} }))) : null,
|
|
144
152
|
react_1.default.createElement(material_1.Divider, null),
|
|
145
153
|
react_1.default.createElement(material_1.Typography, null, "Attributes"),
|
|
146
154
|
react_1.default.createElement(Attributes_1.default, { attributes: feature, ...props, omit: omit, omitSingleLevel: coreDetails }),
|
|
@@ -1,3 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import { SimpleFeatureSerialized } from '../../util';
|
|
3
|
+
import { BaseFeatureWidgetModel } from '../stateModelFactory';
|
|
4
|
+
declare const SequenceFeatureDetails: ({ model, feature, }: {
|
|
5
|
+
model: BaseFeatureWidgetModel;
|
|
6
|
+
feature: SimpleFeatureSerialized;
|
|
7
|
+
}) => React.JSX.Element;
|
|
8
|
+
export default SequenceFeatureDetails;
|
|
@@ -29,115 +29,109 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
29
29
|
const react_1 = __importStar(require("react"));
|
|
30
30
|
const material_1 = require("@mui/material");
|
|
31
31
|
const mui_1 = require("tss-react/mui");
|
|
32
|
+
const mobx_react_1 = require("mobx-react");
|
|
32
33
|
const copy_to_clipboard_1 = __importDefault(require("copy-to-clipboard"));
|
|
33
34
|
// locals
|
|
34
|
-
const
|
|
35
|
+
const hooks_1 = require("./hooks");
|
|
35
36
|
const ui_1 = require("../../ui");
|
|
37
|
+
const util_1 = require("../../util");
|
|
36
38
|
// icons
|
|
37
39
|
const Settings_1 = __importDefault(require("@mui/icons-material/Settings"));
|
|
38
|
-
const hooks_1 = require("./hooks");
|
|
39
40
|
// lazies
|
|
40
|
-
const SettingsDialog = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./SequenceFeatureSettingsDialog'))));
|
|
41
41
|
const SequencePanel = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./SequencePanel'))));
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
margin: theme.spacing(1),
|
|
45
|
-
},
|
|
42
|
+
const SettingsDialog = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./dialogs/SettingsDialog'))));
|
|
43
|
+
const useStyles = (0, mui_1.makeStyles)()({
|
|
46
44
|
formControl: {
|
|
47
45
|
margin: 0,
|
|
46
|
+
marginLeft: 4,
|
|
48
47
|
},
|
|
49
|
-
|
|
50
|
-
marginTop: theme.spacing(1),
|
|
51
|
-
},
|
|
52
|
-
}));
|
|
48
|
+
});
|
|
53
49
|
// set the key on this component to feature.id to clear state after new feature
|
|
54
50
|
// is selected
|
|
55
|
-
|
|
51
|
+
const SequenceFeatureDetails = (0, mobx_react_1.observer)(function ({ model, feature, }) {
|
|
56
52
|
var _a, _b;
|
|
53
|
+
const { sequenceFeatureDetails } = model;
|
|
54
|
+
const { intronBp, upDownBp } = sequenceFeatureDetails;
|
|
57
55
|
const { classes } = useStyles();
|
|
58
|
-
const feature = prefeature;
|
|
59
56
|
const seqPanelRef = (0, react_1.useRef)(null);
|
|
60
|
-
const [intronBp, setIntronBp] = (0, util_1.useLocalStorage)('intronBp', 10);
|
|
61
|
-
const [upDownBp, setUpDownBp] = (0, util_1.useLocalStorage)('upDownBp', 500);
|
|
62
|
-
const [copied, setCopied] = (0, react_1.useState)(false);
|
|
63
|
-
const [copiedHtml, setCopiedHtml] = (0, react_1.useState)(false);
|
|
64
57
|
const [force, setForce] = (0, react_1.useState)(false);
|
|
65
58
|
const hasCDS = (_a = feature.subfeatures) === null || _a === void 0 ? void 0 : _a.some(sub => sub.type === 'CDS');
|
|
66
59
|
const hasExon = (_b = feature.subfeatures) === null || _b === void 0 ? void 0 : _b.some(sub => sub.type === 'exon');
|
|
67
60
|
const hasExonOrCDS = hasExon || hasCDS;
|
|
68
|
-
const { sequence, error } = (0, hooks_1.useFeatureSequence)(model,
|
|
61
|
+
const { sequence, error } = (0, hooks_1.useFeatureSequence)(model, feature, upDownBp, force);
|
|
69
62
|
const [mode, setMode] = (0, react_1.useState)(hasCDS ? 'cds' : hasExon ? 'cdna' : 'genomic');
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
63
|
+
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
64
|
+
react_1.default.createElement("div", null,
|
|
65
|
+
react_1.default.createElement(material_1.FormControl, { className: classes.formControl },
|
|
66
|
+
react_1.default.createElement(material_1.Select, { size: "small", value: mode, onChange: event => setMode(event.target.value) }, Object.entries({
|
|
67
|
+
...(hasCDS
|
|
68
|
+
? {
|
|
69
|
+
cds: 'CDS',
|
|
70
|
+
}
|
|
71
|
+
: {}),
|
|
72
|
+
...(hasCDS
|
|
73
|
+
? {
|
|
74
|
+
protein: 'Protein',
|
|
75
|
+
}
|
|
76
|
+
: {}),
|
|
77
|
+
...(hasExonOrCDS
|
|
78
|
+
? {
|
|
79
|
+
cdna: 'cDNA',
|
|
80
|
+
}
|
|
81
|
+
: {}),
|
|
82
|
+
...(hasExonOrCDS
|
|
83
|
+
? {
|
|
84
|
+
gene: `Genomic w/ full introns`,
|
|
85
|
+
}
|
|
86
|
+
: {}),
|
|
87
|
+
...(hasExonOrCDS
|
|
88
|
+
? {
|
|
89
|
+
gene_updownstream: `Genomic w/ full introns +/- ${upDownBp}bp up+down stream`,
|
|
90
|
+
}
|
|
91
|
+
: {}),
|
|
92
|
+
...(hasExonOrCDS
|
|
93
|
+
? {
|
|
94
|
+
gene_collapsed_intron: `Genomic w/ ${intronBp}bp intron`,
|
|
95
|
+
}
|
|
96
|
+
: {}),
|
|
97
|
+
...(hasExonOrCDS
|
|
98
|
+
? {
|
|
99
|
+
gene_updownstream_collapsed_intron: `Genomic w/ ${intronBp}bp intron +/- ${upDownBp}bp up+down stream `,
|
|
100
|
+
}
|
|
101
|
+
: {}),
|
|
102
|
+
...(!hasExonOrCDS
|
|
103
|
+
? {
|
|
104
|
+
genomic: 'Genomic',
|
|
105
|
+
}
|
|
106
|
+
: {}),
|
|
107
|
+
...(!hasExonOrCDS
|
|
108
|
+
? {
|
|
109
|
+
genomic_sequence_updownstream: `Genomic +/- ${upDownBp}bp up+down stream`,
|
|
110
|
+
}
|
|
111
|
+
: {}),
|
|
112
|
+
}).map(([key, val]) => (react_1.default.createElement(material_1.MenuItem, { key: key, value: key }, val))))),
|
|
113
|
+
react_1.default.createElement(material_1.Button, { className: classes.formControl, variant: "contained", onClick: () => {
|
|
100
114
|
const ref = seqPanelRef.current;
|
|
101
115
|
if (ref) {
|
|
102
116
|
(0, copy_to_clipboard_1.default)(ref.textContent || '', { format: 'text/plain' });
|
|
103
|
-
setCopied(true);
|
|
104
|
-
setTimeout(() => setCopied(false), 1000);
|
|
105
117
|
}
|
|
106
|
-
} },
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
const ref = seqPanelRef.current;
|
|
111
|
-
if (!ref) {
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
118
|
+
} }, "Copy plaintext"),
|
|
119
|
+
react_1.default.createElement(material_1.Button, { className: classes.formControl, variant: "contained", onClick: () => {
|
|
120
|
+
const ref = seqPanelRef.current;
|
|
121
|
+
if (ref) {
|
|
114
122
|
(0, copy_to_clipboard_1.default)(ref.innerHTML, { format: 'text/html' });
|
|
115
|
-
setCopiedHtml(true);
|
|
116
|
-
setTimeout(() => setCopiedHtml(false), 1000);
|
|
117
|
-
} }, copiedHtml ? 'Copied to clipboard!' : 'Copy HTML'))),
|
|
118
|
-
react_1.default.createElement(Settings, { upDownBp: upDownBp, intronBp: intronBp, setIntronBp: setIntronBp, setUpDownBp: setUpDownBp }),
|
|
119
|
-
react_1.default.createElement("br", null),
|
|
120
|
-
feature.type === 'gene' ? (react_1.default.createElement(material_1.Typography, null, "Note: inspect subfeature sequences for protein/CDS computations")) : null,
|
|
121
|
-
error ? (react_1.default.createElement(material_1.Typography, { color: "error" }, `${error}`)) : !sequence ? (react_1.default.createElement(ui_1.LoadingEllipses, null)) : sequence ? ('error' in sequence ? (react_1.default.createElement(react_1.default.Fragment, null,
|
|
122
|
-
react_1.default.createElement(material_1.Typography, { color: "error" }, sequence.error),
|
|
123
|
-
react_1.default.createElement(material_1.Button, { variant: "contained", color: "inherit", onClick: () => setForce(true) }, "Force load"))) : (react_1.default.createElement(react_1.Suspense, { fallback: react_1.default.createElement(ui_1.LoadingEllipses, null) },
|
|
124
|
-
react_1.default.createElement(SequencePanel, { ref: seqPanelRef, feature: feature, mode: mode, sequence: sequence, intronBp: intronBp })))) : (react_1.default.createElement(material_1.Typography, null, "No sequence found"))));
|
|
125
|
-
}
|
|
126
|
-
exports.default = SequenceFeatureDetails;
|
|
127
|
-
function Settings({ intronBp, upDownBp, setIntronBp, setUpDownBp, }) {
|
|
128
|
-
const { classes } = useStyles();
|
|
129
|
-
const [settingsDialogOpen, setSettingsDialogOpen] = (0, react_1.useState)(false);
|
|
130
|
-
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
131
|
-
react_1.default.createElement(material_1.FormControl, { className: classes.formControl },
|
|
132
|
-
react_1.default.createElement(material_1.IconButton, { onClick: () => setSettingsDialogOpen(true) },
|
|
133
|
-
react_1.default.createElement(Settings_1.default, null))),
|
|
134
|
-
settingsDialogOpen ? (react_1.default.createElement(react_1.Suspense, { fallback: null },
|
|
135
|
-
react_1.default.createElement(SettingsDialog, { handleClose: arg => {
|
|
136
|
-
if (arg) {
|
|
137
|
-
const { upDownBp, intronBp } = arg;
|
|
138
|
-
setIntronBp(intronBp);
|
|
139
|
-
setUpDownBp(upDownBp);
|
|
140
123
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
124
|
+
} }, "Copy HTML"),
|
|
125
|
+
react_1.default.createElement(material_1.IconButton, { className: classes.formControl, onClick: () => (0, util_1.getSession)(model).queueDialog(handleClose => [
|
|
126
|
+
SettingsDialog,
|
|
127
|
+
{ model: sequenceFeatureDetails, handleClose },
|
|
128
|
+
]) },
|
|
129
|
+
react_1.default.createElement(Settings_1.default, null))),
|
|
130
|
+
react_1.default.createElement("div", null,
|
|
131
|
+
feature.type === 'gene' ? (react_1.default.createElement(material_1.Typography, null, "Note: inspect subfeature sequences for protein/CDS computations")) : null,
|
|
132
|
+
error ? (react_1.default.createElement(ui_1.ErrorMessage, { error: error })) : !sequence ? (react_1.default.createElement(ui_1.LoadingEllipses, null)) : sequence ? ('error' in sequence ? (react_1.default.createElement(react_1.default.Fragment, null,
|
|
133
|
+
react_1.default.createElement(material_1.Typography, { color: "error" }, sequence.error),
|
|
134
|
+
react_1.default.createElement(material_1.Button, { variant: "contained", color: "inherit", onClick: () => setForce(true) }, "Force load"))) : (react_1.default.createElement(react_1.Suspense, { fallback: react_1.default.createElement(ui_1.LoadingEllipses, null) },
|
|
135
|
+
react_1.default.createElement(SequencePanel, { ref: seqPanelRef, feature: feature, mode: mode, sequence: sequence, model: sequenceFeatureDetails })))) : (react_1.default.createElement(material_1.Typography, null, "No sequence found")))));
|
|
136
|
+
});
|
|
137
|
+
exports.default = SequenceFeatureDetails;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { BaseFeatureWidgetModel } from '../stateModelFactory';
|
|
3
|
+
import { SimpleFeatureSerialized } from '../../util';
|
|
4
|
+
declare const SequenceFeaturePanel: ({ model, feature, }: {
|
|
5
|
+
model: BaseFeatureWidgetModel;
|
|
6
|
+
feature: SimpleFeatureSerialized;
|
|
7
|
+
}) => React.JSX.Element | null;
|
|
8
|
+
export default SequenceFeaturePanel;
|
|
@@ -0,0 +1,67 @@
|
|
|
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 (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
const react_1 = __importStar(require("react"));
|
|
30
|
+
const material_1 = require("@mui/material");
|
|
31
|
+
const mobx_react_1 = require("mobx-react");
|
|
32
|
+
const mui_1 = require("tss-react/mui");
|
|
33
|
+
// locals
|
|
34
|
+
const ui_1 = require("../../ui");
|
|
35
|
+
const util_1 = require("../../util");
|
|
36
|
+
// icons
|
|
37
|
+
const Help_1 = __importDefault(require("@mui/icons-material/Help"));
|
|
38
|
+
// lazies
|
|
39
|
+
const SequenceFeatureDetails = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./SequenceFeatureDetails'))));
|
|
40
|
+
const HelpDialog = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./dialogs/HelpDialog'))));
|
|
41
|
+
const useStyles = (0, mui_1.makeStyles)()(theme => ({
|
|
42
|
+
formControl: {
|
|
43
|
+
margin: 0,
|
|
44
|
+
},
|
|
45
|
+
container: {
|
|
46
|
+
marginTop: theme.spacing(4),
|
|
47
|
+
marginBottom: theme.spacing(4),
|
|
48
|
+
},
|
|
49
|
+
}));
|
|
50
|
+
// display the stitched-together sequence of a gene's CDS, cDNA, or protein
|
|
51
|
+
// sequence. this is a best effort and weird genomic phenomena could lead these
|
|
52
|
+
// to not be 100% accurate
|
|
53
|
+
const SequenceFeaturePanel = (0, mobx_react_1.observer)(function ({ model, feature, }) {
|
|
54
|
+
const { classes } = useStyles();
|
|
55
|
+
const [shown, setShown] = (0, react_1.useState)(false);
|
|
56
|
+
return !model ? null : (react_1.default.createElement("div", { className: classes.container },
|
|
57
|
+
react_1.default.createElement(material_1.FormControl, { className: classes.formControl },
|
|
58
|
+
react_1.default.createElement(material_1.Button, { variant: "contained", onClick: () => setShown(!shown) }, shown ? 'Hide feature sequence' : 'Show feature sequence')),
|
|
59
|
+
react_1.default.createElement(material_1.IconButton, { onClick: () => (0, util_1.getSession)(model).queueDialog(handleClose => [
|
|
60
|
+
HelpDialog,
|
|
61
|
+
{ handleClose },
|
|
62
|
+
]) },
|
|
63
|
+
react_1.default.createElement(Help_1.default, null)),
|
|
64
|
+
shown ? (react_1.default.createElement(react_1.Suspense, { fallback: react_1.default.createElement(ui_1.LoadingEllipses, null) },
|
|
65
|
+
react_1.default.createElement(SequenceFeatureDetails, { key: feature.uniqueId, model: model, feature: feature }))) : null));
|
|
66
|
+
});
|
|
67
|
+
exports.default = SequenceFeaturePanel;
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { SimpleFeatureSerialized } from '../../util';
|
|
3
|
+
import { SeqState } from '../util';
|
|
4
|
+
import { SequenceFeatureDetailsModel } from './model';
|
|
3
5
|
interface SeqPanelProps {
|
|
4
6
|
sequence: SeqState;
|
|
5
|
-
feature:
|
|
7
|
+
feature: SimpleFeatureSerialized;
|
|
6
8
|
mode: string;
|
|
7
|
-
|
|
9
|
+
model: SequenceFeatureDetailsModel;
|
|
8
10
|
}
|
|
9
11
|
declare const SeqPanel: React.ForwardRefExoticComponent<SeqPanelProps & React.RefAttributes<HTMLDivElement>>;
|
|
10
12
|
export default SeqPanel;
|
|
@@ -6,12 +6,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
const react_1 = __importDefault(require("react"));
|
|
7
7
|
const util_1 = require("../../util");
|
|
8
8
|
const util_2 = require("../util");
|
|
9
|
-
const CDNASequence_1 = __importDefault(require("./CDNASequence"));
|
|
10
|
-
const ProteinSequence_1 = __importDefault(require("./ProteinSequence"));
|
|
11
|
-
const GenomicSequence_1 = __importDefault(require("./GenomicSequence"));
|
|
12
|
-
const CDSSequence_1 = __importDefault(require("./CDSSequence"));
|
|
9
|
+
const CDNASequence_1 = __importDefault(require("./seqtypes/CDNASequence"));
|
|
10
|
+
const ProteinSequence_1 = __importDefault(require("./seqtypes/ProteinSequence"));
|
|
11
|
+
const GenomicSequence_1 = __importDefault(require("./seqtypes/GenomicSequence"));
|
|
12
|
+
const CDSSequence_1 = __importDefault(require("./seqtypes/CDSSequence"));
|
|
13
13
|
const SeqPanel = react_1.default.forwardRef(function SeqPanel2(props, ref) {
|
|
14
|
-
const { feature, mode
|
|
14
|
+
const { model, feature, mode } = props;
|
|
15
15
|
let { sequence: { seq, upstream = '', downstream = '' }, } = props;
|
|
16
16
|
const { subfeatures = [] } = feature;
|
|
17
17
|
const children = subfeatures
|
|
@@ -31,7 +31,7 @@ const SeqPanel = react_1.default.forwardRef(function SeqPanel2(props, ref) {
|
|
|
31
31
|
//
|
|
32
32
|
// http://localhost:3000/?config=test_data%2Fconfig.json&session=share-FUl7G1isvF&password=HXh5Y
|
|
33
33
|
let cds = (0, util_2.dedupe)(children.filter(sub => sub.type === 'CDS'));
|
|
34
|
-
let utr = (0, util_2.dedupe)(children.filter(sub => sub.type.match(/utr/i)));
|
|
34
|
+
let utr = (0, util_2.dedupe)(children.filter(sub => { var _a; return (_a = sub.type) === null || _a === void 0 ? void 0 : _a.match(/utr/i); }));
|
|
35
35
|
let exons = (0, util_2.dedupe)(children.filter(sub => sub.type === 'exon'));
|
|
36
36
|
if (!utr.length && cds.length && exons.length) {
|
|
37
37
|
utr = (0, util_2.calculateUTRs)(cds, exons);
|
|
@@ -72,6 +72,6 @@ const SeqPanel = react_1.default.forwardRef(function SeqPanel2(props, ref) {
|
|
|
72
72
|
feature.id ||
|
|
73
73
|
`${feature.refName}:${feature.start + 1}-${feature.end}`}-${mode}\n`),
|
|
74
74
|
react_1.default.createElement("br", null),
|
|
75
|
-
mode === 'genomic' ? (react_1.default.createElement(GenomicSequence_1.default, { sequence: seq })) : mode === 'genomic_sequence_updownstream' ? (react_1.default.createElement(GenomicSequence_1.default, { sequence: seq, upstream: upstream, downstream: downstream })) : mode === 'cds' ? (react_1.default.createElement(CDSSequence_1.default, { cds: cds, sequence: seq })) : mode === 'cdna' ? (react_1.default.createElement(CDNASequence_1.default, { exons: exons, cds: cds, utr: utr, sequence: seq
|
|
75
|
+
mode === 'genomic' ? (react_1.default.createElement(GenomicSequence_1.default, { sequence: seq })) : mode === 'genomic_sequence_updownstream' ? (react_1.default.createElement(GenomicSequence_1.default, { sequence: seq, upstream: upstream, downstream: downstream })) : mode === 'cds' ? (react_1.default.createElement(CDSSequence_1.default, { cds: cds, sequence: seq })) : mode === 'cdna' ? (react_1.default.createElement(CDNASequence_1.default, { model: model, exons: exons, cds: cds, utr: utr, sequence: seq })) : mode === 'protein' ? (react_1.default.createElement(ProteinSequence_1.default, { cds: cds, codonTable: codonTable, sequence: seq })) : mode === 'gene' ? (react_1.default.createElement(CDNASequence_1.default, { model: model, exons: exons, cds: cds, utr: utr, sequence: seq, includeIntrons: true })) : mode === 'gene_collapsed_intron' ? (react_1.default.createElement(CDNASequence_1.default, { model: model, exons: exons, cds: cds, sequence: seq, utr: utr, includeIntrons: true, collapseIntron: true })) : mode === 'gene_updownstream' ? (react_1.default.createElement(CDNASequence_1.default, { model: model, exons: exons, cds: cds, sequence: seq, utr: utr, upstream: upstream, downstream: downstream, includeIntrons: true })) : mode === 'gene_updownstream_collapsed_intron' ? (react_1.default.createElement(CDNASequence_1.default, { model: model, exons: exons, cds: cds, sequence: seq, utr: utr, upstream: upstream, downstream: downstream, includeIntrons: true, collapseIntron: true })) : (react_1.default.createElement("div", null, "Unknown type")))));
|
|
76
76
|
});
|
|
77
77
|
exports.default = SeqPanel;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { SequenceFeatureDetailsModel } from '../model';
|
|
3
|
+
declare const SequenceFeatureSettingsDialog: ({ handleClose, model, }: {
|
|
4
|
+
handleClose: () => void;
|
|
5
|
+
model: SequenceFeatureDetailsModel;
|
|
6
|
+
}) => React.JSX.Element;
|
|
7
|
+
export default SequenceFeatureSettingsDialog;
|
|
@@ -27,6 +27,7 @@ const react_1 = __importStar(require("react"));
|
|
|
27
27
|
const material_1 = require("@mui/material");
|
|
28
28
|
const ui_1 = require("@jbrowse/core/ui");
|
|
29
29
|
const mui_1 = require("tss-react/mui");
|
|
30
|
+
const mobx_react_1 = require("mobx-react");
|
|
30
31
|
const useStyles = (0, mui_1.makeStyles)()(theme => ({
|
|
31
32
|
formElt: {
|
|
32
33
|
margin: theme.spacing(3),
|
|
@@ -36,21 +37,30 @@ const useStyles = (0, mui_1.makeStyles)()(theme => ({
|
|
|
36
37
|
width: '80em',
|
|
37
38
|
},
|
|
38
39
|
}));
|
|
39
|
-
|
|
40
|
+
const SequenceFeatureSettingsDialog = (0, mobx_react_1.observer)(function ({ handleClose, model, }) {
|
|
40
41
|
const { classes } = useStyles();
|
|
41
|
-
const [intronBp, setIntronBp] = (0, react_1.useState)(`${
|
|
42
|
-
const [upDownBp, setUpDownBp] = (0, react_1.useState)(`${
|
|
42
|
+
const [intronBp, setIntronBp] = (0, react_1.useState)(`${model.intronBp}`);
|
|
43
|
+
const [upDownBp, setUpDownBp] = (0, react_1.useState)(`${model.upDownBp}`);
|
|
43
44
|
const intronBpValid = !Number.isNaN(+intronBp);
|
|
44
45
|
const upDownBpValid = !Number.isNaN(+upDownBp);
|
|
45
46
|
return (react_1.default.createElement(ui_1.Dialog, { maxWidth: "xl", open: true, onClose: () => handleClose(), title: "Feature sequence settings" },
|
|
46
47
|
react_1.default.createElement(material_1.DialogContent, { className: classes.dialogContent },
|
|
47
|
-
react_1.default.createElement(
|
|
48
|
-
|
|
48
|
+
react_1.default.createElement("div", null,
|
|
49
|
+
react_1.default.createElement(material_1.TextField, { label: "Number of intronic bases around splice site to display", className: classes.formElt, value: intronBp, helperText: !intronBpValid ? 'Not a number' : '', error: !intronBpValid, onChange: event => setIntronBp(event.target.value) })),
|
|
50
|
+
react_1.default.createElement("div", null,
|
|
51
|
+
react_1.default.createElement(material_1.TextField, { label: "Number of bases up/down stream of feature to display", className: classes.formElt, value: upDownBp, helperText: !upDownBpValid ? 'Not a number' : '', error: !upDownBpValid, onChange: event => setUpDownBp(event.target.value) })),
|
|
52
|
+
react_1.default.createElement("div", null,
|
|
53
|
+
react_1.default.createElement(material_1.FormControl, null,
|
|
54
|
+
react_1.default.createElement(material_1.FormLabel, null, "Sequence capitalization"),
|
|
55
|
+
react_1.default.createElement(material_1.RadioGroup, { value: model.upperCaseCDS ? 'cds' : 'unchanged', onChange: e => model.setUpperCaseCDS(e.target.value === 'cds') },
|
|
56
|
+
react_1.default.createElement(material_1.FormControlLabel, { value: "cds", control: react_1.default.createElement(material_1.Radio, null), label: "Capitalize CDS and lower case everything else" }),
|
|
57
|
+
react_1.default.createElement(material_1.FormControlLabel, { value: "unchanged", control: react_1.default.createElement(material_1.Radio, null), label: "Capitalization from reference genome sequence" }))))),
|
|
49
58
|
react_1.default.createElement(material_1.DialogActions, null,
|
|
50
|
-
react_1.default.createElement(material_1.Button, { onClick: () =>
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
59
|
+
react_1.default.createElement(material_1.Button, { onClick: () => {
|
|
60
|
+
model.setIntronBp(+intronBp);
|
|
61
|
+
model.setUpDownBp(+upDownBp);
|
|
62
|
+
handleClose();
|
|
63
|
+
}, disabled: !intronBpValid || !upDownBpValid, color: "primary", variant: "contained" }, "Submit"),
|
|
54
64
|
react_1.default.createElement(material_1.Button, { onClick: () => handleClose(), color: "secondary", autoFocus: true, variant: "contained" }, "Cancel"))));
|
|
55
|
-
}
|
|
65
|
+
});
|
|
56
66
|
exports.default = SequenceFeatureSettingsDialog;
|
|
@@ -10,9 +10,8 @@ function useFeatureSequence(model, feature, upDownBp, forceLoad) {
|
|
|
10
10
|
const [error, setError] = (0, react_1.useState)();
|
|
11
11
|
(0, react_1.useEffect)(() => {
|
|
12
12
|
var _a;
|
|
13
|
-
let finished = false;
|
|
14
13
|
if (!model) {
|
|
15
|
-
return
|
|
14
|
+
return;
|
|
16
15
|
}
|
|
17
16
|
const { assemblyManager, rpcManager } = (0, util_1.getSession)(model);
|
|
18
17
|
const [assemblyName] = ((_a = model.view) === null || _a === void 0 ? void 0 : _a.assemblyNames) || [];
|
|
@@ -54,9 +53,7 @@ function useFeatureSequence(model, feature, upDownBp, forceLoad) {
|
|
|
54
53
|
const seq = await fetchSeq(start, end, refName);
|
|
55
54
|
const up = await fetchSeq(Math.max(0, b), start, refName);
|
|
56
55
|
const down = await fetchSeq(end, e, refName);
|
|
57
|
-
|
|
58
|
-
setSequence({ seq, upstream: up, downstream: down });
|
|
59
|
-
}
|
|
56
|
+
setSequence({ seq, upstream: up, downstream: down });
|
|
60
57
|
}
|
|
61
58
|
}
|
|
62
59
|
catch (e) {
|
|
@@ -64,9 +61,6 @@ function useFeatureSequence(model, feature, upDownBp, forceLoad) {
|
|
|
64
61
|
setError(e);
|
|
65
62
|
}
|
|
66
63
|
})();
|
|
67
|
-
return () => {
|
|
68
|
-
finished = true;
|
|
69
|
-
};
|
|
70
64
|
}, [feature, model, upDownBp, forceLoad]);
|
|
71
65
|
return { sequence, error };
|
|
72
66
|
}
|
|
@@ -1,72 +1,8 @@
|
|
|
1
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 (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
4
|
};
|
|
28
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const mobx_react_1 = require("mobx-react");
|
|
33
|
-
const ui_1 = require("../../ui");
|
|
34
|
-
const util_1 = require("../../util");
|
|
35
|
-
// icons
|
|
36
|
-
const Help_1 = __importDefault(require("@mui/icons-material/Help"));
|
|
37
|
-
// lazies
|
|
38
|
-
const HelpDialog = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./SequenceHelpDialog'))));
|
|
39
|
-
const SequenceFeatureDetails = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./SequenceFeatureDetails'))));
|
|
40
|
-
const useStyles = (0, mui_1.makeStyles)()(theme => ({
|
|
41
|
-
formControl: {
|
|
42
|
-
margin: 0,
|
|
43
|
-
},
|
|
44
|
-
container: {
|
|
45
|
-
marginTop: theme.spacing(4),
|
|
46
|
-
marginBottom: theme.spacing(4),
|
|
47
|
-
},
|
|
48
|
-
}));
|
|
49
|
-
const SequenceFeatureDetailsHelpButton = (0, mobx_react_1.observer)(function ({ model, }) {
|
|
50
|
-
const { classes } = useStyles();
|
|
51
|
-
const session = (0, util_1.getSession)(model);
|
|
52
|
-
return (react_1.default.createElement(material_1.FormControl, { className: classes.formControl },
|
|
53
|
-
react_1.default.createElement(material_1.IconButton, { onClick: () => session.queueDialog(handleClose => [HelpDialog, { handleClose }]) },
|
|
54
|
-
react_1.default.createElement(Help_1.default, null))));
|
|
55
|
-
});
|
|
56
|
-
// display the stitched-together sequence of a gene's CDS, cDNA, or protein
|
|
57
|
-
// sequence. this is a best effort and weird genomic phenomena could lead these
|
|
58
|
-
// to not be 100% accurate
|
|
59
|
-
function SequenceFeaturePanel({ model, feature }) {
|
|
60
|
-
const { classes } = useStyles();
|
|
61
|
-
const [shown, setShown] = (0, react_1.useState)(false);
|
|
62
|
-
return !model ? null : (react_1.default.createElement("div", { className: classes.container },
|
|
63
|
-
react_1.default.createElement(material_1.Button, { variant: "contained", onClick: () => setShown(!shown) }, shown ? 'Hide feature sequence' : 'Show feature sequence'),
|
|
64
|
-
react_1.default.createElement(SequenceFeatureDetailsHelpButton, { model: model }),
|
|
65
|
-
shown ? (react_1.default.createElement(react_1.Suspense, { fallback: react_1.default.createElement(ui_1.LoadingEllipses, null) },
|
|
66
|
-
react_1.default.createElement(SequenceFeatureDetails
|
|
67
|
-
/* eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion */
|
|
68
|
-
, {
|
|
69
|
-
/* eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion */
|
|
70
|
-
key: feature.uniqueId, model: model, feature: feature }))) : null));
|
|
71
|
-
}
|
|
72
|
-
exports.default = SequenceFeaturePanel;
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var SequenceFeaturePanel_1 = require("./SequenceFeaturePanel");
|
|
8
|
+
Object.defineProperty(exports, "default", { enumerable: true, get: function () { return __importDefault(SequenceFeaturePanel_1).default; } });
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Instance } from 'mobx-state-tree';
|
|
2
|
+
export declare function SequenceFeatureDetailsF(): import("mobx-state-tree").IModelType<{}, {
|
|
3
|
+
intronBp: number;
|
|
4
|
+
upDownBp: number;
|
|
5
|
+
upperCaseCDS: boolean;
|
|
6
|
+
} & {
|
|
7
|
+
setUpDownBp(f: number): void;
|
|
8
|
+
setIntronBp(f: number): void;
|
|
9
|
+
setUpperCaseCDS(f: boolean): void;
|
|
10
|
+
} & {
|
|
11
|
+
afterAttach(): void;
|
|
12
|
+
}, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>;
|
|
13
|
+
export type SequenceFeatureDetailsStateModel = ReturnType<typeof SequenceFeatureDetailsF>;
|
|
14
|
+
export type SequenceFeatureDetailsModel = Instance<SequenceFeatureDetailsStateModel>;
|