@jbrowse/plugin-grid-bookmark 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/dist/GridBookmarkWidget/components/BookmarkGrid.js +52 -57
- package/dist/GridBookmarkWidget/components/Highlight/Highlight.js +8 -17
- package/dist/GridBookmarkWidget/components/Highlight/OverviewHighlight.js +11 -10
- package/dist/GridBookmarkWidget/components/dialogs/ExportBookmarksDialog.js +5 -3
- package/dist/GridBookmarkWidget/components/dialogs/ImportBookmarksDialog.js +52 -29
- package/dist/GridBookmarkWidget/index.d.ts +1 -2
- package/dist/GridBookmarkWidget/index.js +3 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/esm/GridBookmarkWidget/components/BookmarkGrid.js +53 -58
- package/esm/GridBookmarkWidget/components/Highlight/Highlight.js +9 -18
- package/esm/GridBookmarkWidget/components/Highlight/OverviewHighlight.js +12 -11
- package/esm/GridBookmarkWidget/components/dialogs/ExportBookmarksDialog.js +5 -3
- package/esm/GridBookmarkWidget/components/dialogs/ImportBookmarksDialog.js +55 -32
- package/esm/GridBookmarkWidget/index.d.ts +1 -2
- package/esm/GridBookmarkWidget/index.js +2 -2
- package/esm/index.d.ts +1 -1
- package/esm/index.js +1 -1
- package/package.json +2 -2
|
@@ -32,8 +32,6 @@ const material_1 = require("@mui/material");
|
|
|
32
32
|
const mui_1 = require("tss-react/mui");
|
|
33
33
|
const x_data_grid_1 = require("@mui/x-data-grid");
|
|
34
34
|
const util_1 = require("@jbrowse/core/util");
|
|
35
|
-
const useResizeBar_1 = require("@jbrowse/core/ui/useResizeBar");
|
|
36
|
-
const ResizeBar_1 = __importDefault(require("@jbrowse/core/ui/ResizeBar"));
|
|
37
35
|
const ColorPicker_1 = __importDefault(require("@jbrowse/core/ui/ColorPicker"));
|
|
38
36
|
// locals
|
|
39
37
|
const utils_1 = require("../utils");
|
|
@@ -50,7 +48,6 @@ const useStyles = (0, mui_1.makeStyles)()(() => ({
|
|
|
50
48
|
}));
|
|
51
49
|
const BookmarkGrid = (0, mobx_react_1.observer)(function ({ model, }) {
|
|
52
50
|
const { classes, cx } = useStyles();
|
|
53
|
-
const { ref, scrollLeft } = (0, useResizeBar_1.useResizeBar)();
|
|
54
51
|
const { bookmarks, bookmarksWithValidAssemblies, selectedAssemblies, selectedBookmarks, } = model;
|
|
55
52
|
const session = (0, util_1.getSession)(model);
|
|
56
53
|
const selectedSet = new Set(selectedAssemblies);
|
|
@@ -66,64 +63,62 @@ const BookmarkGrid = (0, mobx_react_1.observer)(function ({ model, }) {
|
|
|
66
63
|
correspondingObj: region,
|
|
67
64
|
};
|
|
68
65
|
});
|
|
69
|
-
const
|
|
66
|
+
const widths = [
|
|
70
67
|
50,
|
|
71
68
|
Math.max((0, util_1.measureText)('Bookmark link', 12) + 30, (0, util_1.measureGridWidth)(rows.map(row => row.locString))),
|
|
72
69
|
Math.max((0, util_1.measureText)('Label', 12) + 30, (0, util_1.measureGridWidth)(rows.map(row => row.label))),
|
|
73
70
|
Math.max((0, util_1.measureText)('Assembly', 12) + 30, (0, util_1.measureGridWidth)(rows.map(row => row.assemblyName))),
|
|
74
71
|
100,
|
|
75
|
-
]
|
|
76
|
-
return (react_1.default.createElement(
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
}
|
|
127
|
-
}, rowSelectionModel: selectedBookmarks.map(r => r.id), disableRowSelectionOnClick: true })));
|
|
72
|
+
];
|
|
73
|
+
return (react_1.default.createElement(x_data_grid_1.DataGrid, { autoHeight: true, density: "compact", rows: rows, columns: [
|
|
74
|
+
{
|
|
75
|
+
...x_data_grid_1.GRID_CHECKBOX_SELECTION_COL_DEF,
|
|
76
|
+
width: widths[0],
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
field: 'locString',
|
|
80
|
+
headerName: 'Bookmark link',
|
|
81
|
+
width: widths[1],
|
|
82
|
+
renderCell: ({ value, row }) => (react_1.default.createElement(material_1.Link, { className: cx(classes.link, classes.cell), href: "#", onClick: async (event) => {
|
|
83
|
+
event.preventDefault();
|
|
84
|
+
const { views } = session;
|
|
85
|
+
await (0, utils_1.navToBookmark)(value, row.assemblyName, views, model);
|
|
86
|
+
} }, value)),
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
field: 'label',
|
|
90
|
+
headerName: 'Label',
|
|
91
|
+
width: widths[2],
|
|
92
|
+
editable: true,
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
field: 'assemblyName',
|
|
96
|
+
headerName: 'Assembly',
|
|
97
|
+
width: widths[3],
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
field: 'highlight',
|
|
101
|
+
headerName: 'Highlight',
|
|
102
|
+
width: widths[4],
|
|
103
|
+
renderCell: ({ value, row }) => (react_1.default.createElement(ColorPicker_1.default, { color: value || 'black', onChange: event => {
|
|
104
|
+
model.updateBookmarkHighlight(row, event);
|
|
105
|
+
} })),
|
|
106
|
+
},
|
|
107
|
+
], onCellDoubleClick: ({ row }) => {
|
|
108
|
+
(0, util_1.getSession)(model).queueDialog(onClose => [
|
|
109
|
+
EditBookmarkLabelDialog,
|
|
110
|
+
{ onClose, model, dialogRow: row },
|
|
111
|
+
]);
|
|
112
|
+
}, processRowUpdate: row => {
|
|
113
|
+
const target = rows[row.id];
|
|
114
|
+
model.updateBookmarkLabel(target, row.label);
|
|
115
|
+
return row;
|
|
116
|
+
}, onProcessRowUpdateError: e => session.notifyError(`${e}`, e), checkboxSelection: true, onRowSelectionModelChange: newRowSelectionModel => {
|
|
117
|
+
if (bookmarksWithValidAssemblies.length > 0) {
|
|
118
|
+
model.setSelectedBookmarks(newRowSelectionModel.map(value => ({
|
|
119
|
+
...rows[value],
|
|
120
|
+
})));
|
|
121
|
+
}
|
|
122
|
+
}, rowSelectionModel: selectedBookmarks.map(r => r.id), disableRowSelectionOnClick: true }));
|
|
128
123
|
});
|
|
129
124
|
exports.default = BookmarkGrid;
|
|
@@ -42,35 +42,26 @@ const useStyles = (0, mui_1.makeStyles)()({
|
|
|
42
42
|
},
|
|
43
43
|
});
|
|
44
44
|
const Highlight = (0, mobx_react_1.observer)(function Highlight({ model }) {
|
|
45
|
-
var _a;
|
|
46
45
|
const { classes } = useStyles();
|
|
47
46
|
const session = (0, util_1.getSession)(model);
|
|
48
|
-
const { showBookmarkHighlights, showBookmarkLabels } = model;
|
|
49
47
|
const { assemblyManager } = session;
|
|
50
|
-
const
|
|
48
|
+
const { showBookmarkHighlights, showBookmarkLabels } = model;
|
|
51
49
|
const bookmarkWidget = session.widgets.get('GridBookmark');
|
|
52
|
-
const bookmarks = (0, react_1.useRef)((_a = bookmarkWidget === null || bookmarkWidget === void 0 ? void 0 : bookmarkWidget.bookmarks) !== null && _a !== void 0 ? _a : []);
|
|
53
50
|
(0, react_1.useEffect)(() => {
|
|
54
51
|
if (!bookmarkWidget) {
|
|
55
|
-
|
|
56
|
-
bookmarks.current = newBookmarkWidget.bookmarks;
|
|
52
|
+
session.addWidget('GridBookmarkWidget', 'GridBookmark');
|
|
57
53
|
}
|
|
58
54
|
}, [session, bookmarkWidget]);
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
55
|
+
const set = new Set(model.assemblyNames);
|
|
56
|
+
return showBookmarkHighlights && (bookmarkWidget === null || bookmarkWidget === void 0 ? void 0 : bookmarkWidget.bookmarks)
|
|
57
|
+
? bookmarkWidget.bookmarks
|
|
58
|
+
.filter(value => set.has(value.assemblyName))
|
|
62
59
|
.map(r => {
|
|
63
60
|
var _a;
|
|
64
61
|
const asm = assemblyManager.get(r.assemblyName);
|
|
65
62
|
const refName = (_a = asm === null || asm === void 0 ? void 0 : asm.getCanonicalRefName(r.refName)) !== null && _a !== void 0 ? _a : r.refName;
|
|
66
|
-
const s = model.bpToPx({
|
|
67
|
-
|
|
68
|
-
coord: r.start,
|
|
69
|
-
});
|
|
70
|
-
const e = model.bpToPx({
|
|
71
|
-
refName: refName,
|
|
72
|
-
coord: r.end,
|
|
73
|
-
});
|
|
63
|
+
const s = model.bpToPx({ refName, coord: r.start });
|
|
64
|
+
const e = model.bpToPx({ refName, coord: r.end });
|
|
74
65
|
return s && e
|
|
75
66
|
? {
|
|
76
67
|
width: Math.max(Math.abs(e.offsetPx - s.offsetPx), 3),
|
|
@@ -35,27 +35,28 @@ const useStyles = (0, mui_1.makeStyles)()({
|
|
|
35
35
|
},
|
|
36
36
|
});
|
|
37
37
|
const OverviewHighlight = (0, mobx_react_1.observer)(function OverviewHighlight({ model, overview, }) {
|
|
38
|
-
var _a;
|
|
39
38
|
const { cytobandOffset } = model;
|
|
40
39
|
const session = (0, util_1.getSession)(model);
|
|
41
40
|
const { classes } = useStyles();
|
|
41
|
+
const { assemblyManager } = session;
|
|
42
42
|
const { showBookmarkHighlights, showBookmarkLabels } = model;
|
|
43
|
-
const assemblyNames = new Set(session.assemblyNames);
|
|
44
43
|
const bookmarkWidget = session.widgets.get('GridBookmark');
|
|
45
|
-
const bookmarks = (0, react_1.useRef)((_a = bookmarkWidget === null || bookmarkWidget === void 0 ? void 0 : bookmarkWidget.bookmarks) !== null && _a !== void 0 ? _a : []);
|
|
46
44
|
(0, react_1.useEffect)(() => {
|
|
47
45
|
if (!bookmarkWidget) {
|
|
48
|
-
|
|
49
|
-
bookmarks.current = newBookmarkWidget.bookmarks;
|
|
46
|
+
session.addWidget('GridBookmarkWidget', 'GridBookmark');
|
|
50
47
|
}
|
|
51
48
|
}, [session, bookmarkWidget]);
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
49
|
+
const assemblyNames = new Set(model.assemblyNames);
|
|
50
|
+
return showBookmarkHighlights && (bookmarkWidget === null || bookmarkWidget === void 0 ? void 0 : bookmarkWidget.bookmarks)
|
|
51
|
+
? bookmarkWidget.bookmarks
|
|
52
|
+
.filter(r => assemblyNames.has(r.assemblyName))
|
|
55
53
|
.map(r => {
|
|
54
|
+
var _a;
|
|
55
|
+
const asm = assemblyManager.get(r.assemblyName);
|
|
56
|
+
const refName = (_a = asm === null || asm === void 0 ? void 0 : asm.getCanonicalRefName(r.refName)) !== null && _a !== void 0 ? _a : r.refName;
|
|
56
57
|
const rev = r.reversed;
|
|
57
|
-
const s = overview.bpToPx({
|
|
58
|
-
const e = overview.bpToPx({
|
|
58
|
+
const s = overview.bpToPx({ refName, coord: rev ? r.end : r.start });
|
|
59
|
+
const e = overview.bpToPx({ refName, coord: rev ? r.start : r.end });
|
|
59
60
|
return s !== undefined && e !== undefined
|
|
60
61
|
? {
|
|
61
62
|
width: Math.abs(e - s),
|
|
@@ -36,7 +36,9 @@ const GetApp_1 = __importDefault(require("@mui/icons-material/GetApp"));
|
|
|
36
36
|
const utils_1 = require("../../utils");
|
|
37
37
|
const useStyles = (0, mui_1.makeStyles)()({
|
|
38
38
|
flexItem: {
|
|
39
|
-
|
|
39
|
+
display: 'flex',
|
|
40
|
+
alignItems: 'center',
|
|
41
|
+
gap: '5px',
|
|
40
42
|
},
|
|
41
43
|
container: {
|
|
42
44
|
display: 'flex',
|
|
@@ -55,9 +57,9 @@ const ExportBookmarksDialog = (0, mobx_react_1.observer)(function ExportBookmark
|
|
|
55
57
|
react_1.default.createElement("span", null, "All bookmarks will be exported."),
|
|
56
58
|
react_1.default.createElement("br", null),
|
|
57
59
|
react_1.default.createElement("span", null, "Use the checkboxes to select individual bookmarks to export."))) : ('Only selected bookmarks will be exported.')),
|
|
58
|
-
react_1.default.createElement("div", {
|
|
60
|
+
react_1.default.createElement("div", { className: classes.flexItem },
|
|
59
61
|
react_1.default.createElement(material_1.Typography, null, "Format to download:"),
|
|
60
|
-
react_1.default.createElement(material_1.Select, { size: "small",
|
|
62
|
+
react_1.default.createElement(material_1.Select, { size: "small", value: fileType, onChange: event => setFileType(event.target.value) },
|
|
61
63
|
react_1.default.createElement(material_1.MenuItem, { value: "BED" }, "BED"),
|
|
62
64
|
react_1.default.createElement(material_1.MenuItem, { value: "TSV" }, "TSV")))),
|
|
63
65
|
react_1.default.createElement(material_1.DialogActions, null,
|
|
@@ -34,23 +34,21 @@ const ui_1 = require("@jbrowse/core/ui");
|
|
|
34
34
|
const material_1 = require("@mui/material");
|
|
35
35
|
const io_1 = require("@jbrowse/core/util/io");
|
|
36
36
|
const ui_2 = require("@jbrowse/core/ui");
|
|
37
|
-
const AssemblySelector_1 = __importDefault(require("@jbrowse/core/ui/AssemblySelector"));
|
|
38
37
|
const mui_1 = require("tss-react/mui");
|
|
39
38
|
// icons
|
|
40
39
|
const Publish_1 = __importDefault(require("@mui/icons-material/Publish"));
|
|
41
40
|
const ExpandMore_1 = __importDefault(require("@mui/icons-material/ExpandMore"));
|
|
42
|
-
const Help_1 = __importDefault(require("@mui/icons-material/Help"));
|
|
43
41
|
const utils_1 = require("../../utils");
|
|
44
42
|
const sessionSharing_1 = require("../../sessionSharing");
|
|
45
43
|
const useStyles = (0, mui_1.makeStyles)()(theme => {
|
|
46
44
|
var _a;
|
|
47
45
|
return ({
|
|
48
|
-
flexItem: {
|
|
49
|
-
margin: 5,
|
|
50
|
-
},
|
|
51
46
|
expandIcon: {
|
|
52
47
|
color: ((_a = theme.palette.tertiary) === null || _a === void 0 ? void 0 : _a.contrastText) || '#fff',
|
|
53
48
|
},
|
|
49
|
+
minWidth: {
|
|
50
|
+
minWidth: 500,
|
|
51
|
+
},
|
|
54
52
|
});
|
|
55
53
|
});
|
|
56
54
|
async function getBookmarksFromShareLink(shareLink, shareURL) {
|
|
@@ -62,18 +60,35 @@ async function getBookmarksFromShareLink(shareLink, shareURL) {
|
|
|
62
60
|
const sharedSession = JSON.parse(await (0, utils_1.fromUrlSafeB64)(decryptedSession));
|
|
63
61
|
return sharedSession.sharedBookmarks;
|
|
64
62
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
63
|
+
function guessFileType(header) {
|
|
64
|
+
return header.startsWith('chrom') && header.includes('assembly_name')
|
|
65
|
+
? 'TSV'
|
|
66
|
+
: 'BED';
|
|
67
|
+
}
|
|
68
|
+
async function getBookmarksFromTSVFile(lines) {
|
|
69
|
+
if (lines[0].startsWith('chrom')) {
|
|
70
|
+
lines = lines.slice(1);
|
|
71
|
+
}
|
|
72
|
+
return lines
|
|
73
|
+
.filter(f => !f.startsWith('#'))
|
|
74
|
+
.map(line => {
|
|
75
|
+
const [refName, start, end, label, assemblyName] = line.split('\t');
|
|
76
|
+
return {
|
|
77
|
+
assemblyName: assemblyName,
|
|
78
|
+
refName,
|
|
79
|
+
start: +start,
|
|
80
|
+
end: +end,
|
|
81
|
+
label: label === '.' ? undefined : label,
|
|
82
|
+
};
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
async function getBookmarksFromBEDFile(lines, selectedAsm) {
|
|
86
|
+
return lines
|
|
87
|
+
.filter(f => !f.startsWith('#'))
|
|
73
88
|
.map(line => {
|
|
74
|
-
const [refName, start, end, label
|
|
89
|
+
const [refName, start, end, label] = line.split('\t');
|
|
75
90
|
return {
|
|
76
|
-
assemblyName:
|
|
91
|
+
assemblyName: selectedAsm,
|
|
77
92
|
refName,
|
|
78
93
|
start: +start,
|
|
79
94
|
end: +end,
|
|
@@ -91,31 +106,39 @@ const ImportBookmarksDialog = (0, mobx_react_1.observer)(function ({ onClose, mo
|
|
|
91
106
|
const [selectedAsm, setSelectedAsm] = (0, react_1.useState)(assemblyNames[0]);
|
|
92
107
|
const [expanded, setExpanded] = (0, react_1.useState)('shareLinkAccordion');
|
|
93
108
|
return (react_1.default.createElement(ui_2.Dialog, { open: true, onClose: onClose, maxWidth: "xl", title: "Import bookmarks" },
|
|
94
|
-
react_1.default.createElement(material_1.DialogContent,
|
|
109
|
+
react_1.default.createElement(material_1.DialogContent, { className: classes.minWidth },
|
|
95
110
|
react_1.default.createElement(material_1.Accordion, { expanded: expanded === 'shareLinkAccordion', onChange: () => setExpanded('shareLinkAccordion') },
|
|
96
111
|
react_1.default.createElement(material_1.AccordionSummary, { expandIcon: react_1.default.createElement(ExpandMore_1.default, { className: classes.expandIcon }) },
|
|
97
|
-
react_1.default.createElement(material_1.Typography, { style: { display: 'flex', alignItems: 'center', gap: '5px' } },
|
|
98
|
-
"Import from share link",
|
|
99
|
-
' ',
|
|
100
|
-
react_1.default.createElement(material_1.Tooltip, { title: "The appropriate share link for sharing bookmarks is one generated via the 'Share' button in the 'Bookmarked regions' drawer. Paste it below to import shared bookmarks." },
|
|
101
|
-
react_1.default.createElement(Help_1.default, null)))),
|
|
112
|
+
react_1.default.createElement(material_1.Typography, { style: { display: 'flex', alignItems: 'center', gap: '5px' } }, "Import from share link")),
|
|
102
113
|
react_1.default.createElement(material_1.AccordionDetails, null,
|
|
103
|
-
react_1.default.createElement(material_1.
|
|
114
|
+
react_1.default.createElement(material_1.Typography, null, "Paste a bookmark share link generated by the 'Share' button from the bookmarks widget"),
|
|
115
|
+
react_1.default.createElement(material_1.TextField, { label: "Enter Share URL", variant: "outlined", fullWidth: true, value: shareLink, onChange: e => setShareLink(e.target.value) }))),
|
|
104
116
|
react_1.default.createElement(material_1.Accordion, { expanded: expanded === 'fileAccordion', onChange: () => setExpanded('fileAccordion') },
|
|
105
117
|
react_1.default.createElement(material_1.AccordionSummary, { expandIcon: react_1.default.createElement(ExpandMore_1.default, { className: classes.expandIcon }) },
|
|
106
118
|
react_1.default.createElement(material_1.Typography, null, "Import from file")),
|
|
107
119
|
react_1.default.createElement(material_1.AccordionDetails, null,
|
|
108
|
-
react_1.default.createElement(ui_1.FileSelector, { location: location, setLocation: setLocation, name: "File", description:
|
|
109
|
-
react_1.default.createElement(
|
|
110
|
-
error ?
|
|
120
|
+
react_1.default.createElement(ui_1.FileSelector, { location: location, setLocation: setLocation, name: "File", description: `Choose a BED or TSV format file to import. Required TSV column headers are "chrom, start, end, label, assembly_name".` }),
|
|
121
|
+
react_1.default.createElement(ui_2.AssemblySelector, { onChange: val => setSelectedAsm(val), helperText: `Select the assembly for BED file.`, session: session, selected: selectedAsm }))),
|
|
122
|
+
error ? react_1.default.createElement(ui_1.ErrorMessage, { error: error }) : null),
|
|
111
123
|
react_1.default.createElement(material_1.DialogActions, null,
|
|
112
124
|
react_1.default.createElement(material_1.Button, { variant: "contained", color: "secondary", onClick: onClose }, "Cancel"),
|
|
113
|
-
react_1.default.createElement(material_1.Button, {
|
|
125
|
+
react_1.default.createElement(material_1.Button, { "data-testid": "dialogImport", variant: "contained", color: "primary", disabled: !location && !shareLink, startIcon: react_1.default.createElement(Publish_1.default, null), onClick: async () => {
|
|
114
126
|
try {
|
|
115
|
-
if (location) {
|
|
116
|
-
|
|
127
|
+
if (expanded === 'fileAccordion' && location) {
|
|
128
|
+
const data = await (0, io_1.openLocation)(location).readFile('utf8');
|
|
129
|
+
const lines = data.split(/\n|\r\n|\r/).filter(f => !!f.trim());
|
|
130
|
+
const fileType = guessFileType(lines[0]);
|
|
131
|
+
if (fileType === 'BED') {
|
|
132
|
+
model.importBookmarks(await getBookmarksFromBEDFile(lines, selectedAsm));
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
// TSV
|
|
136
|
+
model.importBookmarks(await getBookmarksFromTSVFile(lines));
|
|
137
|
+
}
|
|
117
138
|
}
|
|
118
|
-
else if (
|
|
139
|
+
else if (expanded === 'shareLinkAccordion' &&
|
|
140
|
+
shareLink &&
|
|
141
|
+
(0, types_1.isSessionWithShareURL)(session)) {
|
|
119
142
|
model.importBookmarks(await getBookmarksFromShareLink(shareLink, session.shareURL));
|
|
120
143
|
}
|
|
121
144
|
onClose();
|
|
@@ -33,7 +33,7 @@ const pluggableElementTypes_1 = require("@jbrowse/core/pluggableElementTypes");
|
|
|
33
33
|
const model_1 = __importDefault(require("./model"));
|
|
34
34
|
const Highlight_1 = __importDefault(require("./components/Highlight"));
|
|
35
35
|
const configSchema = (0, configuration_1.ConfigurationSchema)('GridBookmarkWidget', {});
|
|
36
|
-
|
|
36
|
+
function GridBookmarkWidgetF(pluginManager) {
|
|
37
37
|
pluginManager.addWidgetType(() => {
|
|
38
38
|
return new pluggableElementTypes_1.WidgetType({
|
|
39
39
|
name: 'GridBookmarkWidget',
|
|
@@ -44,4 +44,5 @@ exports.default = (pluginManager) => {
|
|
|
44
44
|
});
|
|
45
45
|
});
|
|
46
46
|
(0, Highlight_1.default)(pluginManager);
|
|
47
|
-
}
|
|
47
|
+
}
|
|
48
|
+
exports.default = GridBookmarkWidgetF;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import Plugin from '@jbrowse/core/Plugin';
|
|
2
2
|
import PluginManager from '@jbrowse/core/PluginManager';
|
|
3
|
-
export default class extends Plugin {
|
|
3
|
+
export default class GridBookmarkPlugin extends Plugin {
|
|
4
4
|
name: string;
|
|
5
5
|
install(pluginManager: PluginManager): void;
|
|
6
6
|
configure(pluginManager: PluginManager): void;
|
package/dist/index.js
CHANGED
|
@@ -11,7 +11,7 @@ const Bookmarks_1 = __importDefault(require("@mui/icons-material/Bookmarks"));
|
|
|
11
11
|
const Highlight_1 = __importDefault(require("@mui/icons-material/Highlight"));
|
|
12
12
|
const Label_1 = __importDefault(require("@mui/icons-material/Label"));
|
|
13
13
|
const GridBookmarkWidget_1 = __importDefault(require("./GridBookmarkWidget"));
|
|
14
|
-
class
|
|
14
|
+
class GridBookmarkPlugin extends Plugin_1.default {
|
|
15
15
|
constructor() {
|
|
16
16
|
super(...arguments);
|
|
17
17
|
this.name = 'GridBookmarkPlugin';
|
|
@@ -180,4 +180,4 @@ class default_1 extends Plugin_1.default {
|
|
|
180
180
|
}
|
|
181
181
|
}
|
|
182
182
|
}
|
|
183
|
-
exports.default =
|
|
183
|
+
exports.default = GridBookmarkPlugin;
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import React, { lazy
|
|
1
|
+
import React, { lazy } from 'react';
|
|
2
2
|
import { observer } from 'mobx-react';
|
|
3
3
|
import { Link } from '@mui/material';
|
|
4
4
|
import { makeStyles } from 'tss-react/mui';
|
|
5
5
|
import { DataGrid, GRID_CHECKBOX_SELECTION_COL_DEF } from '@mui/x-data-grid';
|
|
6
6
|
import { getSession, assembleLocString, measureGridWidth, measureText, } from '@jbrowse/core/util';
|
|
7
|
-
import { useResizeBar } from '@jbrowse/core/ui/useResizeBar';
|
|
8
|
-
import ResizeBar from '@jbrowse/core/ui/ResizeBar';
|
|
9
7
|
import ColorPicker from '@jbrowse/core/ui/ColorPicker';
|
|
10
8
|
// locals
|
|
11
9
|
import { navToBookmark } from '../utils';
|
|
@@ -22,7 +20,6 @@ const useStyles = makeStyles()(() => ({
|
|
|
22
20
|
}));
|
|
23
21
|
const BookmarkGrid = observer(function ({ model, }) {
|
|
24
22
|
const { classes, cx } = useStyles();
|
|
25
|
-
const { ref, scrollLeft } = useResizeBar();
|
|
26
23
|
const { bookmarks, bookmarksWithValidAssemblies, selectedAssemblies, selectedBookmarks, } = model;
|
|
27
24
|
const session = getSession(model);
|
|
28
25
|
const selectedSet = new Set(selectedAssemblies);
|
|
@@ -38,64 +35,62 @@ const BookmarkGrid = observer(function ({ model, }) {
|
|
|
38
35
|
correspondingObj: region,
|
|
39
36
|
};
|
|
40
37
|
});
|
|
41
|
-
const
|
|
38
|
+
const widths = [
|
|
42
39
|
50,
|
|
43
40
|
Math.max(measureText('Bookmark link', 12) + 30, measureGridWidth(rows.map(row => row.locString))),
|
|
44
41
|
Math.max(measureText('Label', 12) + 30, measureGridWidth(rows.map(row => row.label))),
|
|
45
42
|
Math.max(measureText('Assembly', 12) + 30, measureGridWidth(rows.map(row => row.assemblyName))),
|
|
46
43
|
100,
|
|
47
|
-
]
|
|
48
|
-
return (React.createElement(
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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
|
-
}, rowSelectionModel: selectedBookmarks.map(r => r.id), disableRowSelectionOnClick: true })));
|
|
44
|
+
];
|
|
45
|
+
return (React.createElement(DataGrid, { autoHeight: true, density: "compact", rows: rows, columns: [
|
|
46
|
+
{
|
|
47
|
+
...GRID_CHECKBOX_SELECTION_COL_DEF,
|
|
48
|
+
width: widths[0],
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
field: 'locString',
|
|
52
|
+
headerName: 'Bookmark link',
|
|
53
|
+
width: widths[1],
|
|
54
|
+
renderCell: ({ value, row }) => (React.createElement(Link, { className: cx(classes.link, classes.cell), href: "#", onClick: async (event) => {
|
|
55
|
+
event.preventDefault();
|
|
56
|
+
const { views } = session;
|
|
57
|
+
await navToBookmark(value, row.assemblyName, views, model);
|
|
58
|
+
} }, value)),
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
field: 'label',
|
|
62
|
+
headerName: 'Label',
|
|
63
|
+
width: widths[2],
|
|
64
|
+
editable: true,
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
field: 'assemblyName',
|
|
68
|
+
headerName: 'Assembly',
|
|
69
|
+
width: widths[3],
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
field: 'highlight',
|
|
73
|
+
headerName: 'Highlight',
|
|
74
|
+
width: widths[4],
|
|
75
|
+
renderCell: ({ value, row }) => (React.createElement(ColorPicker, { color: value || 'black', onChange: event => {
|
|
76
|
+
model.updateBookmarkHighlight(row, event);
|
|
77
|
+
} })),
|
|
78
|
+
},
|
|
79
|
+
], onCellDoubleClick: ({ row }) => {
|
|
80
|
+
getSession(model).queueDialog(onClose => [
|
|
81
|
+
EditBookmarkLabelDialog,
|
|
82
|
+
{ onClose, model, dialogRow: row },
|
|
83
|
+
]);
|
|
84
|
+
}, processRowUpdate: row => {
|
|
85
|
+
const target = rows[row.id];
|
|
86
|
+
model.updateBookmarkLabel(target, row.label);
|
|
87
|
+
return row;
|
|
88
|
+
}, onProcessRowUpdateError: e => session.notifyError(`${e}`, e), checkboxSelection: true, onRowSelectionModelChange: newRowSelectionModel => {
|
|
89
|
+
if (bookmarksWithValidAssemblies.length > 0) {
|
|
90
|
+
model.setSelectedBookmarks(newRowSelectionModel.map(value => ({
|
|
91
|
+
...rows[value],
|
|
92
|
+
})));
|
|
93
|
+
}
|
|
94
|
+
}, rowSelectionModel: selectedBookmarks.map(r => r.id), disableRowSelectionOnClick: true }));
|
|
100
95
|
});
|
|
101
96
|
export default BookmarkGrid;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useEffect
|
|
1
|
+
import React, { useEffect } from 'react';
|
|
2
2
|
import { observer } from 'mobx-react';
|
|
3
3
|
import { makeStyles } from 'tss-react/mui';
|
|
4
4
|
import { getSession, notEmpty } from '@jbrowse/core/util';
|
|
@@ -14,35 +14,26 @@ const useStyles = makeStyles()({
|
|
|
14
14
|
},
|
|
15
15
|
});
|
|
16
16
|
const Highlight = observer(function Highlight({ model }) {
|
|
17
|
-
var _a;
|
|
18
17
|
const { classes } = useStyles();
|
|
19
18
|
const session = getSession(model);
|
|
20
|
-
const { showBookmarkHighlights, showBookmarkLabels } = model;
|
|
21
19
|
const { assemblyManager } = session;
|
|
22
|
-
const
|
|
20
|
+
const { showBookmarkHighlights, showBookmarkLabels } = model;
|
|
23
21
|
const bookmarkWidget = session.widgets.get('GridBookmark');
|
|
24
|
-
const bookmarks = useRef((_a = bookmarkWidget === null || bookmarkWidget === void 0 ? void 0 : bookmarkWidget.bookmarks) !== null && _a !== void 0 ? _a : []);
|
|
25
22
|
useEffect(() => {
|
|
26
23
|
if (!bookmarkWidget) {
|
|
27
|
-
|
|
28
|
-
bookmarks.current = newBookmarkWidget.bookmarks;
|
|
24
|
+
session.addWidget('GridBookmarkWidget', 'GridBookmark');
|
|
29
25
|
}
|
|
30
26
|
}, [session, bookmarkWidget]);
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
27
|
+
const set = new Set(model.assemblyNames);
|
|
28
|
+
return showBookmarkHighlights && (bookmarkWidget === null || bookmarkWidget === void 0 ? void 0 : bookmarkWidget.bookmarks)
|
|
29
|
+
? bookmarkWidget.bookmarks
|
|
30
|
+
.filter(value => set.has(value.assemblyName))
|
|
34
31
|
.map(r => {
|
|
35
32
|
var _a;
|
|
36
33
|
const asm = assemblyManager.get(r.assemblyName);
|
|
37
34
|
const refName = (_a = asm === null || asm === void 0 ? void 0 : asm.getCanonicalRefName(r.refName)) !== null && _a !== void 0 ? _a : r.refName;
|
|
38
|
-
const s = model.bpToPx({
|
|
39
|
-
|
|
40
|
-
coord: r.start,
|
|
41
|
-
});
|
|
42
|
-
const e = model.bpToPx({
|
|
43
|
-
refName: refName,
|
|
44
|
-
coord: r.end,
|
|
45
|
-
});
|
|
35
|
+
const s = model.bpToPx({ refName, coord: r.start });
|
|
36
|
+
const e = model.bpToPx({ refName, coord: r.end });
|
|
46
37
|
return s && e
|
|
47
38
|
? {
|
|
48
39
|
width: Math.max(Math.abs(e.offsetPx - s.offsetPx), 3),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useEffect
|
|
1
|
+
import React, { useEffect } from 'react';
|
|
2
2
|
import { observer } from 'mobx-react';
|
|
3
3
|
import { makeStyles } from 'tss-react/mui';
|
|
4
4
|
import { getSession, notEmpty } from '@jbrowse/core/util';
|
|
@@ -10,27 +10,28 @@ const useStyles = makeStyles()({
|
|
|
10
10
|
},
|
|
11
11
|
});
|
|
12
12
|
const OverviewHighlight = observer(function OverviewHighlight({ model, overview, }) {
|
|
13
|
-
var _a;
|
|
14
13
|
const { cytobandOffset } = model;
|
|
15
14
|
const session = getSession(model);
|
|
16
15
|
const { classes } = useStyles();
|
|
16
|
+
const { assemblyManager } = session;
|
|
17
17
|
const { showBookmarkHighlights, showBookmarkLabels } = model;
|
|
18
|
-
const assemblyNames = new Set(session.assemblyNames);
|
|
19
18
|
const bookmarkWidget = session.widgets.get('GridBookmark');
|
|
20
|
-
const bookmarks = useRef((_a = bookmarkWidget === null || bookmarkWidget === void 0 ? void 0 : bookmarkWidget.bookmarks) !== null && _a !== void 0 ? _a : []);
|
|
21
19
|
useEffect(() => {
|
|
22
20
|
if (!bookmarkWidget) {
|
|
23
|
-
|
|
24
|
-
bookmarks.current = newBookmarkWidget.bookmarks;
|
|
21
|
+
session.addWidget('GridBookmarkWidget', 'GridBookmark');
|
|
25
22
|
}
|
|
26
23
|
}, [session, bookmarkWidget]);
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
24
|
+
const assemblyNames = new Set(model.assemblyNames);
|
|
25
|
+
return showBookmarkHighlights && (bookmarkWidget === null || bookmarkWidget === void 0 ? void 0 : bookmarkWidget.bookmarks)
|
|
26
|
+
? bookmarkWidget.bookmarks
|
|
27
|
+
.filter(r => assemblyNames.has(r.assemblyName))
|
|
30
28
|
.map(r => {
|
|
29
|
+
var _a;
|
|
30
|
+
const asm = assemblyManager.get(r.assemblyName);
|
|
31
|
+
const refName = (_a = asm === null || asm === void 0 ? void 0 : asm.getCanonicalRefName(r.refName)) !== null && _a !== void 0 ? _a : r.refName;
|
|
31
32
|
const rev = r.reversed;
|
|
32
|
-
const s = overview.bpToPx({
|
|
33
|
-
const e = overview.bpToPx({
|
|
33
|
+
const s = overview.bpToPx({ refName, coord: rev ? r.end : r.start });
|
|
34
|
+
const e = overview.bpToPx({ refName, coord: rev ? r.start : r.end });
|
|
34
35
|
return s !== undefined && e !== undefined
|
|
35
36
|
? {
|
|
36
37
|
width: Math.abs(e - s),
|
|
@@ -8,7 +8,9 @@ import GetAppIcon from '@mui/icons-material/GetApp';
|
|
|
8
8
|
import { downloadBookmarkFile } from '../../utils';
|
|
9
9
|
const useStyles = makeStyles()({
|
|
10
10
|
flexItem: {
|
|
11
|
-
|
|
11
|
+
display: 'flex',
|
|
12
|
+
alignItems: 'center',
|
|
13
|
+
gap: '5px',
|
|
12
14
|
},
|
|
13
15
|
container: {
|
|
14
16
|
display: 'flex',
|
|
@@ -27,9 +29,9 @@ const ExportBookmarksDialog = observer(function ExportBookmarksDialog({ model, o
|
|
|
27
29
|
React.createElement("span", null, "All bookmarks will be exported."),
|
|
28
30
|
React.createElement("br", null),
|
|
29
31
|
React.createElement("span", null, "Use the checkboxes to select individual bookmarks to export."))) : ('Only selected bookmarks will be exported.')),
|
|
30
|
-
React.createElement("div", {
|
|
32
|
+
React.createElement("div", { className: classes.flexItem },
|
|
31
33
|
React.createElement(Typography, null, "Format to download:"),
|
|
32
|
-
React.createElement(Select, { size: "small",
|
|
34
|
+
React.createElement(Select, { size: "small", value: fileType, onChange: event => setFileType(event.target.value) },
|
|
33
35
|
React.createElement(MenuItem, { value: "BED" }, "BED"),
|
|
34
36
|
React.createElement(MenuItem, { value: "TSV" }, "TSV")))),
|
|
35
37
|
React.createElement(DialogActions, null,
|
|
@@ -2,27 +2,25 @@ import React, { useState } from 'react';
|
|
|
2
2
|
import { observer } from 'mobx-react';
|
|
3
3
|
import { getSession } from '@jbrowse/core/util';
|
|
4
4
|
import { isSessionWithShareURL } from '@jbrowse/core/util/types';
|
|
5
|
-
import { FileSelector } from '@jbrowse/core/ui';
|
|
6
|
-
import {
|
|
5
|
+
import { ErrorMessage, FileSelector } from '@jbrowse/core/ui';
|
|
6
|
+
import { Accordion, AccordionSummary, AccordionDetails, Button, DialogContent, DialogActions, TextField, Typography, } from '@mui/material';
|
|
7
7
|
import { openLocation } from '@jbrowse/core/util/io';
|
|
8
|
-
import { Dialog } from '@jbrowse/core/ui';
|
|
9
|
-
import AssemblySelector from '@jbrowse/core/ui/AssemblySelector';
|
|
8
|
+
import { Dialog, AssemblySelector } from '@jbrowse/core/ui';
|
|
10
9
|
import { makeStyles } from 'tss-react/mui';
|
|
11
10
|
// icons
|
|
12
11
|
import ImportIcon from '@mui/icons-material/Publish';
|
|
13
12
|
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
|
|
14
|
-
import HelpIcon from '@mui/icons-material/Help';
|
|
15
13
|
import { fromUrlSafeB64 } from '../../utils';
|
|
16
14
|
import { readSessionFromDynamo } from '../../sessionSharing';
|
|
17
15
|
const useStyles = makeStyles()(theme => {
|
|
18
16
|
var _a;
|
|
19
17
|
return ({
|
|
20
|
-
flexItem: {
|
|
21
|
-
margin: 5,
|
|
22
|
-
},
|
|
23
18
|
expandIcon: {
|
|
24
19
|
color: ((_a = theme.palette.tertiary) === null || _a === void 0 ? void 0 : _a.contrastText) || '#fff',
|
|
25
20
|
},
|
|
21
|
+
minWidth: {
|
|
22
|
+
minWidth: 500,
|
|
23
|
+
},
|
|
26
24
|
});
|
|
27
25
|
});
|
|
28
26
|
async function getBookmarksFromShareLink(shareLink, shareURL) {
|
|
@@ -34,18 +32,35 @@ async function getBookmarksFromShareLink(shareLink, shareURL) {
|
|
|
34
32
|
const sharedSession = JSON.parse(await fromUrlSafeB64(decryptedSession));
|
|
35
33
|
return sharedSession.sharedBookmarks;
|
|
36
34
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
35
|
+
function guessFileType(header) {
|
|
36
|
+
return header.startsWith('chrom') && header.includes('assembly_name')
|
|
37
|
+
? 'TSV'
|
|
38
|
+
: 'BED';
|
|
39
|
+
}
|
|
40
|
+
async function getBookmarksFromTSVFile(lines) {
|
|
41
|
+
if (lines[0].startsWith('chrom')) {
|
|
42
|
+
lines = lines.slice(1);
|
|
43
|
+
}
|
|
44
|
+
return lines
|
|
45
|
+
.filter(f => !f.startsWith('#'))
|
|
46
|
+
.map(line => {
|
|
47
|
+
const [refName, start, end, label, assemblyName] = line.split('\t');
|
|
48
|
+
return {
|
|
49
|
+
assemblyName: assemblyName,
|
|
50
|
+
refName,
|
|
51
|
+
start: +start,
|
|
52
|
+
end: +end,
|
|
53
|
+
label: label === '.' ? undefined : label,
|
|
54
|
+
};
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
async function getBookmarksFromBEDFile(lines, selectedAsm) {
|
|
58
|
+
return lines
|
|
59
|
+
.filter(f => !f.startsWith('#'))
|
|
45
60
|
.map(line => {
|
|
46
|
-
const [refName, start, end, label
|
|
61
|
+
const [refName, start, end, label] = line.split('\t');
|
|
47
62
|
return {
|
|
48
|
-
assemblyName:
|
|
63
|
+
assemblyName: selectedAsm,
|
|
49
64
|
refName,
|
|
50
65
|
start: +start,
|
|
51
66
|
end: +end,
|
|
@@ -63,31 +78,39 @@ const ImportBookmarksDialog = observer(function ({ onClose, model, }) {
|
|
|
63
78
|
const [selectedAsm, setSelectedAsm] = useState(assemblyNames[0]);
|
|
64
79
|
const [expanded, setExpanded] = useState('shareLinkAccordion');
|
|
65
80
|
return (React.createElement(Dialog, { open: true, onClose: onClose, maxWidth: "xl", title: "Import bookmarks" },
|
|
66
|
-
React.createElement(DialogContent,
|
|
81
|
+
React.createElement(DialogContent, { className: classes.minWidth },
|
|
67
82
|
React.createElement(Accordion, { expanded: expanded === 'shareLinkAccordion', onChange: () => setExpanded('shareLinkAccordion') },
|
|
68
83
|
React.createElement(AccordionSummary, { expandIcon: React.createElement(ExpandMoreIcon, { className: classes.expandIcon }) },
|
|
69
|
-
React.createElement(Typography, { style: { display: 'flex', alignItems: 'center', gap: '5px' } },
|
|
70
|
-
"Import from share link",
|
|
71
|
-
' ',
|
|
72
|
-
React.createElement(Tooltip, { title: "The appropriate share link for sharing bookmarks is one generated via the 'Share' button in the 'Bookmarked regions' drawer. Paste it below to import shared bookmarks." },
|
|
73
|
-
React.createElement(HelpIcon, null)))),
|
|
84
|
+
React.createElement(Typography, { style: { display: 'flex', alignItems: 'center', gap: '5px' } }, "Import from share link")),
|
|
74
85
|
React.createElement(AccordionDetails, null,
|
|
75
|
-
React.createElement(
|
|
86
|
+
React.createElement(Typography, null, "Paste a bookmark share link generated by the 'Share' button from the bookmarks widget"),
|
|
87
|
+
React.createElement(TextField, { label: "Enter Share URL", variant: "outlined", fullWidth: true, value: shareLink, onChange: e => setShareLink(e.target.value) }))),
|
|
76
88
|
React.createElement(Accordion, { expanded: expanded === 'fileAccordion', onChange: () => setExpanded('fileAccordion') },
|
|
77
89
|
React.createElement(AccordionSummary, { expandIcon: React.createElement(ExpandMoreIcon, { className: classes.expandIcon }) },
|
|
78
90
|
React.createElement(Typography, null, "Import from file")),
|
|
79
91
|
React.createElement(AccordionDetails, null,
|
|
80
|
-
React.createElement(FileSelector, { location: location, setLocation: setLocation, name: "File", description:
|
|
81
|
-
React.createElement(AssemblySelector, { onChange: val => setSelectedAsm(val), helperText: `Select the assembly
|
|
82
|
-
error ?
|
|
92
|
+
React.createElement(FileSelector, { location: location, setLocation: setLocation, name: "File", description: `Choose a BED or TSV format file to import. Required TSV column headers are "chrom, start, end, label, assembly_name".` }),
|
|
93
|
+
React.createElement(AssemblySelector, { onChange: val => setSelectedAsm(val), helperText: `Select the assembly for BED file.`, session: session, selected: selectedAsm }))),
|
|
94
|
+
error ? React.createElement(ErrorMessage, { error: error }) : null),
|
|
83
95
|
React.createElement(DialogActions, null,
|
|
84
96
|
React.createElement(Button, { variant: "contained", color: "secondary", onClick: onClose }, "Cancel"),
|
|
85
|
-
React.createElement(Button, {
|
|
97
|
+
React.createElement(Button, { "data-testid": "dialogImport", variant: "contained", color: "primary", disabled: !location && !shareLink, startIcon: React.createElement(ImportIcon, null), onClick: async () => {
|
|
86
98
|
try {
|
|
87
|
-
if (location) {
|
|
88
|
-
|
|
99
|
+
if (expanded === 'fileAccordion' && location) {
|
|
100
|
+
const data = await openLocation(location).readFile('utf8');
|
|
101
|
+
const lines = data.split(/\n|\r\n|\r/).filter(f => !!f.trim());
|
|
102
|
+
const fileType = guessFileType(lines[0]);
|
|
103
|
+
if (fileType === 'BED') {
|
|
104
|
+
model.importBookmarks(await getBookmarksFromBEDFile(lines, selectedAsm));
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
// TSV
|
|
108
|
+
model.importBookmarks(await getBookmarksFromTSVFile(lines));
|
|
109
|
+
}
|
|
89
110
|
}
|
|
90
|
-
else if (
|
|
111
|
+
else if (expanded === 'shareLinkAccordion' &&
|
|
112
|
+
shareLink &&
|
|
113
|
+
isSessionWithShareURL(session)) {
|
|
91
114
|
model.importBookmarks(await getBookmarksFromShareLink(shareLink, session.shareURL));
|
|
92
115
|
}
|
|
93
116
|
onClose();
|
|
@@ -5,7 +5,7 @@ import { WidgetType } from '@jbrowse/core/pluggableElementTypes';
|
|
|
5
5
|
import stateModelFactory from './model';
|
|
6
6
|
import AddHighlightModelF from './components/Highlight';
|
|
7
7
|
const configSchema = ConfigurationSchema('GridBookmarkWidget', {});
|
|
8
|
-
export default (pluginManager)
|
|
8
|
+
export default function GridBookmarkWidgetF(pluginManager) {
|
|
9
9
|
pluginManager.addWidgetType(() => {
|
|
10
10
|
return new WidgetType({
|
|
11
11
|
name: 'GridBookmarkWidget',
|
|
@@ -16,4 +16,4 @@ export default (pluginManager) => {
|
|
|
16
16
|
});
|
|
17
17
|
});
|
|
18
18
|
AddHighlightModelF(pluginManager);
|
|
19
|
-
}
|
|
19
|
+
}
|
package/esm/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import Plugin from '@jbrowse/core/Plugin';
|
|
2
2
|
import PluginManager from '@jbrowse/core/PluginManager';
|
|
3
|
-
export default class extends Plugin {
|
|
3
|
+
export default class GridBookmarkPlugin extends Plugin {
|
|
4
4
|
name: string;
|
|
5
5
|
install(pluginManager: PluginManager): void;
|
|
6
6
|
configure(pluginManager: PluginManager): void;
|
package/esm/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import BookmarksIcon from '@mui/icons-material/Bookmarks';
|
|
|
6
6
|
import HighlightIcon from '@mui/icons-material/Highlight';
|
|
7
7
|
import LabelIcon from '@mui/icons-material/Label';
|
|
8
8
|
import GridBookmarkWidgetF from './GridBookmarkWidget';
|
|
9
|
-
export default class extends Plugin {
|
|
9
|
+
export default class GridBookmarkPlugin extends Plugin {
|
|
10
10
|
constructor() {
|
|
11
11
|
super(...arguments);
|
|
12
12
|
this.name = 'GridBookmarkPlugin';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jbrowse/plugin-grid-bookmark",
|
|
3
|
-
"version": "2.11.
|
|
3
|
+
"version": "2.11.2",
|
|
4
4
|
"description": "JBrowse 2 grid bookmark widget",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jbrowse",
|
|
@@ -59,5 +59,5 @@
|
|
|
59
59
|
"distModule": "esm/index.js",
|
|
60
60
|
"srcModule": "src/index.ts",
|
|
61
61
|
"module": "esm/index.js",
|
|
62
|
-
"gitHead": "
|
|
62
|
+
"gitHead": "511048cb6965f0bf624c96de244e7fd47fce17d6"
|
|
63
63
|
}
|