@jbrowse/plugin-grid-bookmark 2.13.1 → 2.14.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.
- package/dist/GridBookmarkWidget/components/AssemblySelector.js +4 -2
- package/dist/GridBookmarkWidget/components/BookmarkGrid.js +3 -1
- package/dist/GridBookmarkWidget/components/GridBookmarkWidget.d.ts +1 -1
- package/dist/GridBookmarkWidget/components/GridBookmarkWidget.js +0 -3
- package/dist/GridBookmarkWidget/components/Highlight/Highlight.js +5 -3
- package/dist/GridBookmarkWidget/components/Highlight/OverviewHighlight.js +1 -1
- package/dist/GridBookmarkWidget/components/Highlight/index.js +6 -6
- package/dist/GridBookmarkWidget/components/dialogs/DeleteBookmarksDialog.js +3 -1
- package/dist/GridBookmarkWidget/components/dialogs/EditBookmarkLabelDialog.js +4 -2
- package/dist/GridBookmarkWidget/components/dialogs/EditHighlightColorDialog.js +6 -2
- package/dist/GridBookmarkWidget/components/dialogs/ExportBookmarksDialog.js +3 -1
- package/dist/GridBookmarkWidget/components/dialogs/HighlightSettingsDialog.js +3 -1
- package/dist/GridBookmarkWidget/components/dialogs/ImportBookmarksDialog.js +22 -17
- package/dist/GridBookmarkWidget/components/dialogs/ShareBookmarksDialog.js +8 -12
- package/dist/GridBookmarkWidget/model.d.ts +2 -2
- package/dist/GridBookmarkWidget/model.js +5 -1
- package/dist/GridBookmarkWidget/utils.js +6 -3
- package/dist/index.js +23 -8
- package/esm/GridBookmarkWidget/components/AssemblySelector.js +4 -2
- package/esm/GridBookmarkWidget/components/BookmarkGrid.js +3 -1
- package/esm/GridBookmarkWidget/components/GridBookmarkWidget.d.ts +1 -1
- package/esm/GridBookmarkWidget/components/GridBookmarkWidget.js +0 -3
- package/esm/GridBookmarkWidget/components/Highlight/Highlight.js +5 -3
- package/esm/GridBookmarkWidget/components/Highlight/OverviewHighlight.js +1 -1
- package/esm/GridBookmarkWidget/components/Highlight/index.js +6 -6
- package/esm/GridBookmarkWidget/components/dialogs/DeleteBookmarksDialog.js +3 -1
- package/esm/GridBookmarkWidget/components/dialogs/EditBookmarkLabelDialog.js +4 -2
- package/esm/GridBookmarkWidget/components/dialogs/EditHighlightColorDialog.js +6 -2
- package/esm/GridBookmarkWidget/components/dialogs/ExportBookmarksDialog.js +3 -1
- package/esm/GridBookmarkWidget/components/dialogs/HighlightSettingsDialog.js +3 -1
- package/esm/GridBookmarkWidget/components/dialogs/ImportBookmarksDialog.js +22 -17
- package/esm/GridBookmarkWidget/components/dialogs/ShareBookmarksDialog.js +8 -12
- package/esm/GridBookmarkWidget/model.d.ts +2 -2
- package/esm/GridBookmarkWidget/model.js +5 -1
- package/esm/GridBookmarkWidget/utils.js +6 -3
- package/esm/index.js +23 -8
- package/package.json +3 -3
|
@@ -8,14 +8,16 @@ const mobx_react_1 = require("mobx-react");
|
|
|
8
8
|
const material_1 = require("@mui/material");
|
|
9
9
|
const AssemblySelector = (0, mobx_react_1.observer)(function ({ model, }) {
|
|
10
10
|
const { validAssemblies, selectedAssemblies } = model;
|
|
11
|
-
const noAssemblies = validAssemblies.size === 0
|
|
11
|
+
const noAssemblies = validAssemblies.size === 0;
|
|
12
12
|
const label = 'Select assemblies';
|
|
13
13
|
const id = 'select-assemblies-label';
|
|
14
14
|
const selectedSet = new Set(selectedAssemblies);
|
|
15
15
|
const isAllSelected = [...validAssemblies].every(e => selectedSet.has(e));
|
|
16
16
|
return (react_1.default.createElement(material_1.FormControl, { disabled: noAssemblies, fullWidth: true },
|
|
17
17
|
react_1.default.createElement(material_1.InputLabel, { id: id }, label),
|
|
18
|
-
react_1.default.createElement(material_1.Select, { labelId: id, multiple: true, value: selectedAssemblies, onChange: event =>
|
|
18
|
+
react_1.default.createElement(material_1.Select, { labelId: id, multiple: true, value: selectedAssemblies, onChange: event => {
|
|
19
|
+
model.setSelectedAssemblies([...event.target.value]);
|
|
20
|
+
}, input: react_1.default.createElement(material_1.OutlinedInput, { label: label }), renderValue: selected => selected.join(', ') },
|
|
19
21
|
react_1.default.createElement(material_1.MenuItem, { onClickCapture: event => {
|
|
20
22
|
// onClickCapture allows us to avoid the parent Select onChange from triggering
|
|
21
23
|
if (isAllSelected) {
|
|
@@ -110,7 +110,9 @@ const BookmarkGrid = (0, mobx_react_1.observer)(function ({ model, }) {
|
|
|
110
110
|
const target = rows[row.id];
|
|
111
111
|
model.updateBookmarkLabel(target, row.label);
|
|
112
112
|
return row;
|
|
113
|
-
}, onProcessRowUpdateError: e =>
|
|
113
|
+
}, onProcessRowUpdateError: e => {
|
|
114
|
+
session.notifyError(`${e}`, e);
|
|
115
|
+
}, checkboxSelection: true, onRowSelectionModelChange: newRowSelectionModel => {
|
|
114
116
|
if (bookmarksWithValidAssemblies.length > 0) {
|
|
115
117
|
model.setSelectedBookmarks(newRowSelectionModel.map(value => ({
|
|
116
118
|
...rows[value],
|
|
@@ -57,9 +57,6 @@ const useStyles = (0, mui_1.makeStyles)()({
|
|
|
57
57
|
});
|
|
58
58
|
const GridBookmarkWidget = (0, mobx_react_1.observer)(function GridBookmarkWidget({ model, }) {
|
|
59
59
|
const { classes } = useStyles();
|
|
60
|
-
if (!model) {
|
|
61
|
-
return null;
|
|
62
|
-
}
|
|
63
60
|
return (react_1.default.createElement("div", null,
|
|
64
61
|
react_1.default.createElement(material_1.Alert, { severity: "info" },
|
|
65
62
|
"Click and type within the ",
|
|
@@ -72,15 +72,17 @@ const Highlight = (0, mobx_react_1.observer)(function Highlight({ model }) {
|
|
|
72
72
|
: undefined;
|
|
73
73
|
})
|
|
74
74
|
.filter(util_1.notEmpty)
|
|
75
|
-
.map(({ left, width, highlight, label }, idx) => (react_1.default.createElement("div", {
|
|
75
|
+
.map(({ left, width, highlight, label }, idx) => (react_1.default.createElement("div", {
|
|
76
|
+
/* biome-ignore lint/suspicious/noArrayIndexKey: */
|
|
77
|
+
key: `${left}_${width}_${idx}`, className: classes.highlight, style: {
|
|
76
78
|
left,
|
|
77
79
|
width,
|
|
78
80
|
background: highlight,
|
|
79
81
|
} }, showBookmarkLabels ? (react_1.default.createElement(material_1.Tooltip, { title: label, arrow: true },
|
|
80
82
|
react_1.default.createElement(Bookmark_1.default, { fontSize: "small", sx: {
|
|
81
|
-
color:
|
|
83
|
+
color: (0, colord_1.colord)(highlight).alpha() !== 0
|
|
82
84
|
? (0, colord_1.colord)(highlight).alpha(0.8).toRgbString()
|
|
83
|
-
: (0, colord_1.colord)(highlight).alpha(0).toRgbString()
|
|
85
|
+
: (0, colord_1.colord)(highlight).alpha(0).toRgbString(),
|
|
84
86
|
} }))) : null)))
|
|
85
87
|
: null;
|
|
86
88
|
});
|
|
@@ -69,7 +69,7 @@ const OverviewHighlight = (0, mobx_react_1.observer)(function OverviewHighlight(
|
|
|
69
69
|
.filter(util_1.notEmpty)
|
|
70
70
|
.map((obj, idx) => {
|
|
71
71
|
const { left, width, highlight, label } = obj;
|
|
72
|
-
return (react_1.default.createElement(material_1.Tooltip, { key: JSON.stringify(obj)
|
|
72
|
+
return (react_1.default.createElement(material_1.Tooltip, { key: `${JSON.stringify(obj)}-${idx}`, title: showBookmarkLabels ? label : '', arrow: true },
|
|
73
73
|
react_1.default.createElement("div", { className: classes.highlight, style: {
|
|
74
74
|
left,
|
|
75
75
|
width,
|
|
@@ -11,18 +11,18 @@ const OverviewHighlight_1 = __importDefault(require("./OverviewHighlight"));
|
|
|
11
11
|
function AddHighlightModelF(pluginManager) {
|
|
12
12
|
pluginManager.addToExtensionPoint('LinearGenomeView-TracksContainerComponent',
|
|
13
13
|
// @ts-expect-error
|
|
14
|
-
(rest
|
|
14
|
+
(rest, { model }) => {
|
|
15
15
|
return [
|
|
16
|
-
...rest,
|
|
17
|
-
react_1.default.createElement(Highlight_1.default, { key:
|
|
16
|
+
...(rest || []),
|
|
17
|
+
react_1.default.createElement(Highlight_1.default, { key: "highlight_grid_bookmark", model: model }),
|
|
18
18
|
];
|
|
19
19
|
});
|
|
20
20
|
pluginManager.addToExtensionPoint('LinearGenomeView-OverviewScalebarComponent',
|
|
21
21
|
// @ts-expect-error
|
|
22
|
-
(rest
|
|
22
|
+
(rest, { model, overview }) => {
|
|
23
23
|
return [
|
|
24
|
-
...rest,
|
|
25
|
-
react_1.default.createElement(OverviewHighlight_1.default, { key:
|
|
24
|
+
...(rest || []),
|
|
25
|
+
react_1.default.createElement(OverviewHighlight_1.default, { key: "overview_highlight_grid_bookmark", model: model, overview: overview }),
|
|
26
26
|
];
|
|
27
27
|
});
|
|
28
28
|
}
|
|
@@ -17,7 +17,9 @@ const DeleteBookmarksDialog = (0, mobx_react_1.observer)(function ({ onClose, mo
|
|
|
17
17
|
react_1.default.createElement("br", null),
|
|
18
18
|
react_1.default.createElement("span", null, "Use the checkboxes to select individual bookmarks to delete."))) : ('Only selected bookmarks will be deleted.'))),
|
|
19
19
|
react_1.default.createElement(material_1.DialogActions, null,
|
|
20
|
-
react_1.default.createElement(material_1.Button, { variant: "contained", color: "secondary", onClick: () =>
|
|
20
|
+
react_1.default.createElement(material_1.Button, { variant: "contained", color: "secondary", onClick: () => {
|
|
21
|
+
onClose();
|
|
22
|
+
} }, "Cancel"),
|
|
21
23
|
react_1.default.createElement(material_1.Button, { variant: "contained", color: "primary", onClick: () => {
|
|
22
24
|
if (deleteAll) {
|
|
23
25
|
model.clearAllBookmarks();
|
|
@@ -37,10 +37,12 @@ const EditBookmarkLabelDialog = (0, mobx_react_1.observer)(function ({ model, on
|
|
|
37
37
|
' ',
|
|
38
38
|
react_1.default.createElement("strong", null, (0, util_1.assembleLocString)(dialogRow.correspondingObj)),
|
|
39
39
|
":"),
|
|
40
|
-
react_1.default.createElement(material_1.TextField, { fullWidth: true, inputProps: { 'data-testid': 'edit-bookmark-label-field' }, variant: "outlined", value: newLabel, onChange: e =>
|
|
40
|
+
react_1.default.createElement(material_1.TextField, { fullWidth: true, inputProps: { 'data-testid': 'edit-bookmark-label-field' }, variant: "outlined", value: newLabel, onChange: e => {
|
|
41
|
+
setNewLabel(e.target.value);
|
|
42
|
+
}, autoFocus: true })),
|
|
41
43
|
react_1.default.createElement(material_1.DialogActions, null,
|
|
42
44
|
react_1.default.createElement(material_1.Button, { variant: "contained", color: "primary", onClick: () => {
|
|
43
|
-
if (newLabel
|
|
45
|
+
if (newLabel) {
|
|
44
46
|
model.updateBookmarkLabel(dialogRow, newLabel);
|
|
45
47
|
}
|
|
46
48
|
setNewLabel('');
|
|
@@ -37,9 +37,13 @@ const EditHighlightColorDialog = (0, mobx_react_1.observer)(function ({ onClose,
|
|
|
37
37
|
react_1.default.createElement(material_1.DialogContent, null,
|
|
38
38
|
react_1.default.createElement(material_1.Typography, { variant: "h6" }, "Bulk highlight selector"),
|
|
39
39
|
react_1.default.createElement(material_1.Alert, { severity: "info" }, editNone ? (react_1.default.createElement("span", null, "Use the checkboxes to select individual bookmarks to edit.")) : ('Only selected bookmarks will be edited.')),
|
|
40
|
-
!editNone ? (react_1.default.createElement(ColorPicker_1.ColorPicker, { color: color, onChange: event =>
|
|
40
|
+
!editNone ? (react_1.default.createElement(ColorPicker_1.ColorPicker, { color: color, onChange: event => {
|
|
41
|
+
setColor(event);
|
|
42
|
+
} })) : null),
|
|
41
43
|
react_1.default.createElement(material_1.DialogActions, null,
|
|
42
|
-
react_1.default.createElement(material_1.Button, { variant: "contained", color: "secondary", onClick: () =>
|
|
44
|
+
react_1.default.createElement(material_1.Button, { variant: "contained", color: "secondary", onClick: () => {
|
|
45
|
+
onClose();
|
|
46
|
+
} }, "Cancel"),
|
|
43
47
|
react_1.default.createElement(material_1.Button, { variant: "contained", color: "primary", onClick: () => {
|
|
44
48
|
model.updateBulkBookmarkHighlights(color);
|
|
45
49
|
onClose();
|
|
@@ -59,7 +59,9 @@ const ExportBookmarksDialog = (0, mobx_react_1.observer)(function ExportBookmark
|
|
|
59
59
|
react_1.default.createElement("span", null, "Use the checkboxes to select individual bookmarks to export."))) : ('Only selected bookmarks will be exported.')),
|
|
60
60
|
react_1.default.createElement("div", { className: classes.flexItem },
|
|
61
61
|
react_1.default.createElement(material_1.Typography, null, "Format to download:"),
|
|
62
|
-
react_1.default.createElement(material_1.Select, { size: "small", value: fileType, onChange: event =>
|
|
62
|
+
react_1.default.createElement(material_1.Select, { size: "small", value: fileType, onChange: event => {
|
|
63
|
+
setFileType(event.target.value);
|
|
64
|
+
} },
|
|
63
65
|
react_1.default.createElement(material_1.MenuItem, { value: "BED" }, "BED"),
|
|
64
66
|
react_1.default.createElement(material_1.MenuItem, { value: "TSV" }, "TSV")))),
|
|
65
67
|
react_1.default.createElement(material_1.DialogActions, null,
|
|
@@ -22,6 +22,8 @@ const HighlightSettingsDialog = (0, mobx_react_1.observer)(function ({ onClose,
|
|
|
22
22
|
} }),
|
|
23
23
|
react_1.default.createElement(material_1.Typography, null, "Toggle 'bookmark' icon on LGV tracks"))),
|
|
24
24
|
react_1.default.createElement(material_1.DialogActions, null,
|
|
25
|
-
react_1.default.createElement(material_1.Button, { variant: "contained", color: "primary", onClick: () =>
|
|
25
|
+
react_1.default.createElement(material_1.Button, { variant: "contained", color: "primary", onClick: () => {
|
|
26
|
+
onClose();
|
|
27
|
+
} }, "Close"))));
|
|
26
28
|
});
|
|
27
29
|
exports.default = HighlightSettingsDialog;
|
|
@@ -40,17 +40,14 @@ const Publish_1 = __importDefault(require("@mui/icons-material/Publish"));
|
|
|
40
40
|
const ExpandMore_1 = __importDefault(require("@mui/icons-material/ExpandMore"));
|
|
41
41
|
const utils_1 = require("../../utils");
|
|
42
42
|
const sessionSharing_1 = require("../../sessionSharing");
|
|
43
|
-
const useStyles = (0, mui_1.makeStyles)()(theme => {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
},
|
|
52
|
-
});
|
|
53
|
-
});
|
|
43
|
+
const useStyles = (0, mui_1.makeStyles)()(theme => ({
|
|
44
|
+
expandIcon: {
|
|
45
|
+
color: theme.palette.tertiary.contrastText || '#fff',
|
|
46
|
+
},
|
|
47
|
+
minWidth: {
|
|
48
|
+
minWidth: 500,
|
|
49
|
+
},
|
|
50
|
+
}));
|
|
54
51
|
async function getBookmarksFromShareLink(shareLink, shareURL) {
|
|
55
52
|
const defaultURL = 'https://share.jbrowse.org/api/v1/';
|
|
56
53
|
const urlParams = new URL(shareLink);
|
|
@@ -75,7 +72,7 @@ async function getBookmarksFromTSVFile(lines) {
|
|
|
75
72
|
const [refName, start, end, label, assemblyName] = line.split('\t');
|
|
76
73
|
return {
|
|
77
74
|
assemblyName: assemblyName,
|
|
78
|
-
refName,
|
|
75
|
+
refName: refName,
|
|
79
76
|
start: +start,
|
|
80
77
|
end: +end,
|
|
81
78
|
label: label === '.' ? undefined : label,
|
|
@@ -89,7 +86,7 @@ async function getBookmarksFromBEDFile(lines, selectedAsm) {
|
|
|
89
86
|
const [refName, start, end, label] = line.split('\t');
|
|
90
87
|
return {
|
|
91
88
|
assemblyName: selectedAsm,
|
|
92
|
-
refName,
|
|
89
|
+
refName: refName,
|
|
93
90
|
start: +start,
|
|
94
91
|
end: +end,
|
|
95
92
|
label: label === '.' ? undefined : label,
|
|
@@ -107,18 +104,26 @@ const ImportBookmarksDialog = (0, mobx_react_1.observer)(function ({ onClose, mo
|
|
|
107
104
|
const [expanded, setExpanded] = (0, react_1.useState)('shareLinkAccordion');
|
|
108
105
|
return (react_1.default.createElement(ui_2.Dialog, { open: true, onClose: onClose, maxWidth: "xl", title: "Import bookmarks" },
|
|
109
106
|
react_1.default.createElement(material_1.DialogContent, { className: classes.minWidth },
|
|
110
|
-
react_1.default.createElement(material_1.Accordion, { expanded: expanded === 'shareLinkAccordion', onChange: () =>
|
|
107
|
+
react_1.default.createElement(material_1.Accordion, { expanded: expanded === 'shareLinkAccordion', onChange: () => {
|
|
108
|
+
setExpanded('shareLinkAccordion');
|
|
109
|
+
} },
|
|
111
110
|
react_1.default.createElement(material_1.AccordionSummary, { expandIcon: react_1.default.createElement(ExpandMore_1.default, { className: classes.expandIcon }) },
|
|
112
111
|
react_1.default.createElement(material_1.Typography, { style: { display: 'flex', alignItems: 'center', gap: '5px' } }, "Import from share link")),
|
|
113
112
|
react_1.default.createElement(material_1.AccordionDetails, null,
|
|
114
113
|
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 =>
|
|
116
|
-
|
|
114
|
+
react_1.default.createElement(material_1.TextField, { label: "Enter Share URL", variant: "outlined", fullWidth: true, value: shareLink, onChange: e => {
|
|
115
|
+
setShareLink(e.target.value);
|
|
116
|
+
} }))),
|
|
117
|
+
react_1.default.createElement(material_1.Accordion, { expanded: expanded === 'fileAccordion', onChange: () => {
|
|
118
|
+
setExpanded('fileAccordion');
|
|
119
|
+
} },
|
|
117
120
|
react_1.default.createElement(material_1.AccordionSummary, { expandIcon: react_1.default.createElement(ExpandMore_1.default, { className: classes.expandIcon }) },
|
|
118
121
|
react_1.default.createElement(material_1.Typography, null, "Import from file")),
|
|
119
122
|
react_1.default.createElement(material_1.AccordionDetails, null,
|
|
120
123
|
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 =>
|
|
124
|
+
react_1.default.createElement(ui_2.AssemblySelector, { onChange: val => {
|
|
125
|
+
setSelectedAsm(val);
|
|
126
|
+
}, helperText: 'Select the assembly for BED file.', session: session, selected: selectedAsm }))),
|
|
122
127
|
error ? react_1.default.createElement(ui_1.ErrorMessage, { error: error }) : null),
|
|
123
128
|
react_1.default.createElement(material_1.DialogActions, null,
|
|
124
129
|
react_1.default.createElement(material_1.Button, { variant: "contained", color: "secondary", onClick: onClose }, "Cancel"),
|
|
@@ -54,7 +54,8 @@ const ShareBookmarksDialog = (0, mobx_react_1.observer)(function ({ onClose, mod
|
|
|
54
54
|
? model.allBookmarksModel
|
|
55
55
|
: model.sharedBookmarksModel;
|
|
56
56
|
(0, react_1.useEffect)(() => {
|
|
57
|
-
|
|
57
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
58
|
+
;
|
|
58
59
|
(async () => {
|
|
59
60
|
try {
|
|
60
61
|
if (!(0, util_1.isSessionWithShareURL)(session)) {
|
|
@@ -64,14 +65,12 @@ const ShareBookmarksDialog = (0, mobx_react_1.observer)(function ({ onClose, mod
|
|
|
64
65
|
const snap = (0, mobx_state_tree_1.getSnapshot)(bookmarksToShare);
|
|
65
66
|
const locationUrl = new URL(window.location.href);
|
|
66
67
|
const result = await (0, sessionSharing_1.shareSessionToDynamo)(snap, session.shareURL, locationUrl.href);
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
setLoading(false);
|
|
74
|
-
}
|
|
68
|
+
const params = new URLSearchParams(locationUrl.search);
|
|
69
|
+
params.set('bookmarks', `share-${result.json.sessionId}`);
|
|
70
|
+
params.set('password', result.password);
|
|
71
|
+
locationUrl.search = params.toString();
|
|
72
|
+
setUrl(locationUrl.href);
|
|
73
|
+
setLoading(false);
|
|
75
74
|
}
|
|
76
75
|
catch (e) {
|
|
77
76
|
setError(e);
|
|
@@ -80,9 +79,6 @@ const ShareBookmarksDialog = (0, mobx_react_1.observer)(function ({ onClose, mod
|
|
|
80
79
|
setLoading(false);
|
|
81
80
|
}
|
|
82
81
|
})();
|
|
83
|
-
return () => {
|
|
84
|
-
cancelled = true;
|
|
85
|
-
};
|
|
86
82
|
}, [bookmarksToShare, session]);
|
|
87
83
|
return (react_1.default.createElement(ui_1.Dialog, { open: true, onClose: onClose, title: "Share bookmarks" },
|
|
88
84
|
react_1.default.createElement(material_1.DialogContent, { style: { display: 'flex', flexFlow: 'column', gap: '5px' } },
|
|
@@ -21,8 +21,8 @@ declare const LabeledRegionModel: import("mobx-state-tree").IModelType<{
|
|
|
21
21
|
export interface IExtendedLGV extends LinearGenomeViewModel {
|
|
22
22
|
showBookmarkHighlights: boolean;
|
|
23
23
|
showBookmarkLabels: boolean;
|
|
24
|
-
toggleShowBookmarkHighlights: (arg: boolean) =>
|
|
25
|
-
toggleShowBookmarkLabels: (arg: boolean) =>
|
|
24
|
+
toggleShowBookmarkHighlights: (arg: boolean) => void;
|
|
25
|
+
toggleShowBookmarkLabels: (arg: boolean) => void;
|
|
26
26
|
}
|
|
27
27
|
export interface ILabeledRegionModel extends SnapshotIn<typeof LabeledRegionModel> {
|
|
28
28
|
refName: string;
|
|
@@ -161,7 +161,9 @@ function f(_pluginManager) {
|
|
|
161
161
|
* #action
|
|
162
162
|
*/
|
|
163
163
|
updateBulkBookmarkHighlights(color) {
|
|
164
|
-
self.selectedBookmarks.forEach(bookmark =>
|
|
164
|
+
self.selectedBookmarks.forEach(bookmark => {
|
|
165
|
+
this.updateBookmarkHighlight(bookmark, color);
|
|
166
|
+
});
|
|
165
167
|
},
|
|
166
168
|
/**
|
|
167
169
|
* #action
|
|
@@ -182,6 +184,7 @@ function f(_pluginManager) {
|
|
|
182
184
|
const { views } = (0, util_1.getSession)(self);
|
|
183
185
|
views.forEach(view => {
|
|
184
186
|
var _a;
|
|
187
|
+
// @ts-expect-error
|
|
185
188
|
(_a = view.toggleShowBookmarkHighlights) === null || _a === void 0 ? void 0 : _a.call(view, toggle);
|
|
186
189
|
});
|
|
187
190
|
},
|
|
@@ -192,6 +195,7 @@ function f(_pluginManager) {
|
|
|
192
195
|
const { views } = (0, util_1.getSession)(self);
|
|
193
196
|
views.forEach(view => {
|
|
194
197
|
var _a;
|
|
198
|
+
// @ts-expect-error
|
|
195
199
|
(_a = view.toggleShowBookmarkLabels) === null || _a === void 0 ? void 0 : _a.call(view, toggle);
|
|
196
200
|
});
|
|
197
201
|
},
|
|
@@ -68,9 +68,12 @@ function downloadBookmarkFile(fileFormat, model) {
|
|
|
68
68
|
const { label } = bookmark;
|
|
69
69
|
const labelVal = label === '' ? '.' : label;
|
|
70
70
|
const line = `${bookmark.refName}\t${bookmark.start}\t${bookmark.end}\t${labelVal}\n`;
|
|
71
|
-
fileContents[bookmark.assemblyName]
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
if (fileContents[bookmark.assemblyName]) {
|
|
72
|
+
fileContents[bookmark.assemblyName].push(line);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
fileContents[bookmark.assemblyName] = [line];
|
|
76
|
+
}
|
|
74
77
|
});
|
|
75
78
|
for (const assembly in fileContents) {
|
|
76
79
|
const fileContent = fileContents[assembly].reduce((a, b) => a + b, fileHeader);
|
package/dist/index.js
CHANGED
|
@@ -67,9 +67,8 @@ class GridBookmarkPlugin extends Plugin_1.default {
|
|
|
67
67
|
navigateNewestBookmark() {
|
|
68
68
|
const session = (0, util_1.getSession)(self);
|
|
69
69
|
const bookmarkWidget = self.activateBookmarkWidget();
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
self.navTo(regions.at(-1));
|
|
70
|
+
if (bookmarkWidget.bookmarks.length) {
|
|
71
|
+
self.navTo(bookmarkWidget.bookmarks.at(-1));
|
|
73
72
|
}
|
|
74
73
|
else {
|
|
75
74
|
session.notify('There are no recent bookmarks to navigate to.', 'info');
|
|
@@ -79,7 +78,12 @@ class GridBookmarkPlugin extends Plugin_1.default {
|
|
|
79
78
|
if (self.id === (0, util_1.getSession)(self).focusedViewId) {
|
|
80
79
|
const selectedRegions = self.getSelectedRegions(undefined, undefined);
|
|
81
80
|
const bookmarkWidget = self.activateBookmarkWidget();
|
|
82
|
-
|
|
81
|
+
if (!selectedRegions.length) {
|
|
82
|
+
throw new Error('no region selected');
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
bookmarkWidget.addBookmark(selectedRegions[0]);
|
|
86
|
+
}
|
|
83
87
|
}
|
|
84
88
|
},
|
|
85
89
|
}))
|
|
@@ -103,21 +107,27 @@ class GridBookmarkPlugin extends Plugin_1.default {
|
|
|
103
107
|
{
|
|
104
108
|
label: 'Bookmark current region',
|
|
105
109
|
icon: Bookmark_1.default,
|
|
106
|
-
onClick: () =>
|
|
110
|
+
onClick: () => {
|
|
111
|
+
self.bookmarkCurrentRegion();
|
|
112
|
+
},
|
|
107
113
|
},
|
|
108
114
|
{
|
|
109
115
|
label: 'Toggle bookmark highlights',
|
|
110
116
|
icon: Highlight_1.default,
|
|
111
117
|
type: 'checkbox',
|
|
112
118
|
checked: self.showBookmarkHighlights,
|
|
113
|
-
onClick: () =>
|
|
119
|
+
onClick: () => {
|
|
120
|
+
self.toggleShowBookmarkHighlights();
|
|
121
|
+
},
|
|
114
122
|
},
|
|
115
123
|
{
|
|
116
124
|
label: 'Toggle bookmark labels',
|
|
117
125
|
icon: Label_1.default,
|
|
118
126
|
type: 'checkbox',
|
|
119
127
|
checked: self.showBookmarkLabels,
|
|
120
|
-
onClick: () =>
|
|
128
|
+
onClick: () => {
|
|
129
|
+
self.toggleShowBookmarkLabels();
|
|
130
|
+
},
|
|
121
131
|
},
|
|
122
132
|
],
|
|
123
133
|
},
|
|
@@ -133,7 +143,12 @@ class GridBookmarkPlugin extends Plugin_1.default {
|
|
|
133
143
|
const { leftOffset, rightOffset } = self;
|
|
134
144
|
const selectedRegions = self.getSelectedRegions(leftOffset, rightOffset);
|
|
135
145
|
const bookmarkWidget = self.activateBookmarkWidget();
|
|
136
|
-
|
|
146
|
+
if (!selectedRegions.length) {
|
|
147
|
+
throw new Error('no regions selected');
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
bookmarkWidget.addBookmark(selectedRegions[0]);
|
|
151
|
+
}
|
|
137
152
|
},
|
|
138
153
|
},
|
|
139
154
|
];
|
|
@@ -3,14 +3,16 @@ import { observer } from 'mobx-react';
|
|
|
3
3
|
import { Checkbox, FormControl, InputLabel, ListItemText, MenuItem, OutlinedInput, Select, } from '@mui/material';
|
|
4
4
|
const AssemblySelector = observer(function ({ model, }) {
|
|
5
5
|
const { validAssemblies, selectedAssemblies } = model;
|
|
6
|
-
const noAssemblies = validAssemblies.size === 0
|
|
6
|
+
const noAssemblies = validAssemblies.size === 0;
|
|
7
7
|
const label = 'Select assemblies';
|
|
8
8
|
const id = 'select-assemblies-label';
|
|
9
9
|
const selectedSet = new Set(selectedAssemblies);
|
|
10
10
|
const isAllSelected = [...validAssemblies].every(e => selectedSet.has(e));
|
|
11
11
|
return (React.createElement(FormControl, { disabled: noAssemblies, fullWidth: true },
|
|
12
12
|
React.createElement(InputLabel, { id: id }, label),
|
|
13
|
-
React.createElement(Select, { labelId: id, multiple: true, value: selectedAssemblies, onChange: event =>
|
|
13
|
+
React.createElement(Select, { labelId: id, multiple: true, value: selectedAssemblies, onChange: event => {
|
|
14
|
+
model.setSelectedAssemblies([...event.target.value]);
|
|
15
|
+
}, input: React.createElement(OutlinedInput, { label: label }), renderValue: selected => selected.join(', ') },
|
|
14
16
|
React.createElement(MenuItem, { onClickCapture: event => {
|
|
15
17
|
// onClickCapture allows us to avoid the parent Select onChange from triggering
|
|
16
18
|
if (isAllSelected) {
|
|
@@ -82,7 +82,9 @@ const BookmarkGrid = observer(function ({ model, }) {
|
|
|
82
82
|
const target = rows[row.id];
|
|
83
83
|
model.updateBookmarkLabel(target, row.label);
|
|
84
84
|
return row;
|
|
85
|
-
}, onProcessRowUpdateError: e =>
|
|
85
|
+
}, onProcessRowUpdateError: e => {
|
|
86
|
+
session.notifyError(`${e}`, e);
|
|
87
|
+
}, checkboxSelection: true, onRowSelectionModelChange: newRowSelectionModel => {
|
|
86
88
|
if (bookmarksWithValidAssemblies.length > 0) {
|
|
87
89
|
model.setSelectedBookmarks(newRowSelectionModel.map(value => ({
|
|
88
90
|
...rows[value],
|
|
@@ -29,9 +29,6 @@ const useStyles = makeStyles()({
|
|
|
29
29
|
});
|
|
30
30
|
const GridBookmarkWidget = observer(function GridBookmarkWidget({ model, }) {
|
|
31
31
|
const { classes } = useStyles();
|
|
32
|
-
if (!model) {
|
|
33
|
-
return null;
|
|
34
|
-
}
|
|
35
32
|
return (React.createElement("div", null,
|
|
36
33
|
React.createElement(Alert, { severity: "info" },
|
|
37
34
|
"Click and type within the ",
|
|
@@ -44,15 +44,17 @@ const Highlight = observer(function Highlight({ model }) {
|
|
|
44
44
|
: undefined;
|
|
45
45
|
})
|
|
46
46
|
.filter(notEmpty)
|
|
47
|
-
.map(({ left, width, highlight, label }, idx) => (React.createElement("div", {
|
|
47
|
+
.map(({ left, width, highlight, label }, idx) => (React.createElement("div", {
|
|
48
|
+
/* biome-ignore lint/suspicious/noArrayIndexKey: */
|
|
49
|
+
key: `${left}_${width}_${idx}`, className: classes.highlight, style: {
|
|
48
50
|
left,
|
|
49
51
|
width,
|
|
50
52
|
background: highlight,
|
|
51
53
|
} }, showBookmarkLabels ? (React.createElement(Tooltip, { title: label, arrow: true },
|
|
52
54
|
React.createElement(BookmarkIcon, { fontSize: "small", sx: {
|
|
53
|
-
color:
|
|
55
|
+
color: colord(highlight).alpha() !== 0
|
|
54
56
|
? colord(highlight).alpha(0.8).toRgbString()
|
|
55
|
-
: colord(highlight).alpha(0).toRgbString()
|
|
57
|
+
: colord(highlight).alpha(0).toRgbString(),
|
|
56
58
|
} }))) : null)))
|
|
57
59
|
: null;
|
|
58
60
|
});
|
|
@@ -44,7 +44,7 @@ const OverviewHighlight = observer(function OverviewHighlight({ model, overview,
|
|
|
44
44
|
.filter(notEmpty)
|
|
45
45
|
.map((obj, idx) => {
|
|
46
46
|
const { left, width, highlight, label } = obj;
|
|
47
|
-
return (React.createElement(Tooltip, { key: JSON.stringify(obj)
|
|
47
|
+
return (React.createElement(Tooltip, { key: `${JSON.stringify(obj)}-${idx}`, title: showBookmarkLabels ? label : '', arrow: true },
|
|
48
48
|
React.createElement("div", { className: classes.highlight, style: {
|
|
49
49
|
left,
|
|
50
50
|
width,
|
|
@@ -5,18 +5,18 @@ import OverviewHighlight from './OverviewHighlight';
|
|
|
5
5
|
export default function AddHighlightModelF(pluginManager) {
|
|
6
6
|
pluginManager.addToExtensionPoint('LinearGenomeView-TracksContainerComponent',
|
|
7
7
|
// @ts-expect-error
|
|
8
|
-
(rest
|
|
8
|
+
(rest, { model }) => {
|
|
9
9
|
return [
|
|
10
|
-
...rest,
|
|
11
|
-
React.createElement(Highlight, { key:
|
|
10
|
+
...(rest || []),
|
|
11
|
+
React.createElement(Highlight, { key: "highlight_grid_bookmark", model: model }),
|
|
12
12
|
];
|
|
13
13
|
});
|
|
14
14
|
pluginManager.addToExtensionPoint('LinearGenomeView-OverviewScalebarComponent',
|
|
15
15
|
// @ts-expect-error
|
|
16
|
-
(rest
|
|
16
|
+
(rest, { model, overview }) => {
|
|
17
17
|
return [
|
|
18
|
-
...rest,
|
|
19
|
-
React.createElement(OverviewHighlight, { key:
|
|
18
|
+
...(rest || []),
|
|
19
|
+
React.createElement(OverviewHighlight, { key: "overview_highlight_grid_bookmark", model: model, overview: overview }),
|
|
20
20
|
];
|
|
21
21
|
});
|
|
22
22
|
}
|
|
@@ -12,7 +12,9 @@ const DeleteBookmarksDialog = observer(function ({ onClose, model, }) {
|
|
|
12
12
|
React.createElement("br", null),
|
|
13
13
|
React.createElement("span", null, "Use the checkboxes to select individual bookmarks to delete."))) : ('Only selected bookmarks will be deleted.'))),
|
|
14
14
|
React.createElement(DialogActions, null,
|
|
15
|
-
React.createElement(Button, { variant: "contained", color: "secondary", onClick: () =>
|
|
15
|
+
React.createElement(Button, { variant: "contained", color: "secondary", onClick: () => {
|
|
16
|
+
onClose();
|
|
17
|
+
} }, "Cancel"),
|
|
16
18
|
React.createElement(Button, { variant: "contained", color: "primary", onClick: () => {
|
|
17
19
|
if (deleteAll) {
|
|
18
20
|
model.clearAllBookmarks();
|
|
@@ -12,10 +12,12 @@ const EditBookmarkLabelDialog = observer(function ({ model, onClose, dialogRow,
|
|
|
12
12
|
' ',
|
|
13
13
|
React.createElement("strong", null, assembleLocString(dialogRow.correspondingObj)),
|
|
14
14
|
":"),
|
|
15
|
-
React.createElement(TextField, { fullWidth: true, inputProps: { 'data-testid': 'edit-bookmark-label-field' }, variant: "outlined", value: newLabel, onChange: e =>
|
|
15
|
+
React.createElement(TextField, { fullWidth: true, inputProps: { 'data-testid': 'edit-bookmark-label-field' }, variant: "outlined", value: newLabel, onChange: e => {
|
|
16
|
+
setNewLabel(e.target.value);
|
|
17
|
+
}, autoFocus: true })),
|
|
16
18
|
React.createElement(DialogActions, null,
|
|
17
19
|
React.createElement(Button, { variant: "contained", color: "primary", onClick: () => {
|
|
18
|
-
if (newLabel
|
|
20
|
+
if (newLabel) {
|
|
19
21
|
model.updateBookmarkLabel(dialogRow, newLabel);
|
|
20
22
|
}
|
|
21
23
|
setNewLabel('');
|
|
@@ -12,9 +12,13 @@ const EditHighlightColorDialog = observer(function ({ onClose, model, }) {
|
|
|
12
12
|
React.createElement(DialogContent, null,
|
|
13
13
|
React.createElement(Typography, { variant: "h6" }, "Bulk highlight selector"),
|
|
14
14
|
React.createElement(Alert, { severity: "info" }, editNone ? (React.createElement("span", null, "Use the checkboxes to select individual bookmarks to edit.")) : ('Only selected bookmarks will be edited.')),
|
|
15
|
-
!editNone ? (React.createElement(ColorPicker, { color: color, onChange: event =>
|
|
15
|
+
!editNone ? (React.createElement(ColorPicker, { color: color, onChange: event => {
|
|
16
|
+
setColor(event);
|
|
17
|
+
} })) : null),
|
|
16
18
|
React.createElement(DialogActions, null,
|
|
17
|
-
React.createElement(Button, { variant: "contained", color: "secondary", onClick: () =>
|
|
19
|
+
React.createElement(Button, { variant: "contained", color: "secondary", onClick: () => {
|
|
20
|
+
onClose();
|
|
21
|
+
} }, "Cancel"),
|
|
18
22
|
React.createElement(Button, { variant: "contained", color: "primary", onClick: () => {
|
|
19
23
|
model.updateBulkBookmarkHighlights(color);
|
|
20
24
|
onClose();
|
|
@@ -31,7 +31,9 @@ const ExportBookmarksDialog = observer(function ExportBookmarksDialog({ model, o
|
|
|
31
31
|
React.createElement("span", null, "Use the checkboxes to select individual bookmarks to export."))) : ('Only selected bookmarks will be exported.')),
|
|
32
32
|
React.createElement("div", { className: classes.flexItem },
|
|
33
33
|
React.createElement(Typography, null, "Format to download:"),
|
|
34
|
-
React.createElement(Select, { size: "small", value: fileType, onChange: event =>
|
|
34
|
+
React.createElement(Select, { size: "small", value: fileType, onChange: event => {
|
|
35
|
+
setFileType(event.target.value);
|
|
36
|
+
} },
|
|
35
37
|
React.createElement(MenuItem, { value: "BED" }, "BED"),
|
|
36
38
|
React.createElement(MenuItem, { value: "TSV" }, "TSV")))),
|
|
37
39
|
React.createElement(DialogActions, null,
|
|
@@ -17,6 +17,8 @@ const HighlightSettingsDialog = observer(function ({ onClose, model, }) {
|
|
|
17
17
|
} }),
|
|
18
18
|
React.createElement(Typography, null, "Toggle 'bookmark' icon on LGV tracks"))),
|
|
19
19
|
React.createElement(DialogActions, null,
|
|
20
|
-
React.createElement(Button, { variant: "contained", color: "primary", onClick: () =>
|
|
20
|
+
React.createElement(Button, { variant: "contained", color: "primary", onClick: () => {
|
|
21
|
+
onClose();
|
|
22
|
+
} }, "Close"))));
|
|
21
23
|
});
|
|
22
24
|
export default HighlightSettingsDialog;
|
|
@@ -12,17 +12,14 @@ import ImportIcon from '@mui/icons-material/Publish';
|
|
|
12
12
|
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
|
|
13
13
|
import { fromUrlSafeB64 } from '../../utils';
|
|
14
14
|
import { readSessionFromDynamo } from '../../sessionSharing';
|
|
15
|
-
const useStyles = makeStyles()(theme => {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
},
|
|
24
|
-
});
|
|
25
|
-
});
|
|
15
|
+
const useStyles = makeStyles()(theme => ({
|
|
16
|
+
expandIcon: {
|
|
17
|
+
color: theme.palette.tertiary.contrastText || '#fff',
|
|
18
|
+
},
|
|
19
|
+
minWidth: {
|
|
20
|
+
minWidth: 500,
|
|
21
|
+
},
|
|
22
|
+
}));
|
|
26
23
|
async function getBookmarksFromShareLink(shareLink, shareURL) {
|
|
27
24
|
const defaultURL = 'https://share.jbrowse.org/api/v1/';
|
|
28
25
|
const urlParams = new URL(shareLink);
|
|
@@ -47,7 +44,7 @@ async function getBookmarksFromTSVFile(lines) {
|
|
|
47
44
|
const [refName, start, end, label, assemblyName] = line.split('\t');
|
|
48
45
|
return {
|
|
49
46
|
assemblyName: assemblyName,
|
|
50
|
-
refName,
|
|
47
|
+
refName: refName,
|
|
51
48
|
start: +start,
|
|
52
49
|
end: +end,
|
|
53
50
|
label: label === '.' ? undefined : label,
|
|
@@ -61,7 +58,7 @@ async function getBookmarksFromBEDFile(lines, selectedAsm) {
|
|
|
61
58
|
const [refName, start, end, label] = line.split('\t');
|
|
62
59
|
return {
|
|
63
60
|
assemblyName: selectedAsm,
|
|
64
|
-
refName,
|
|
61
|
+
refName: refName,
|
|
65
62
|
start: +start,
|
|
66
63
|
end: +end,
|
|
67
64
|
label: label === '.' ? undefined : label,
|
|
@@ -79,18 +76,26 @@ const ImportBookmarksDialog = observer(function ({ onClose, model, }) {
|
|
|
79
76
|
const [expanded, setExpanded] = useState('shareLinkAccordion');
|
|
80
77
|
return (React.createElement(Dialog, { open: true, onClose: onClose, maxWidth: "xl", title: "Import bookmarks" },
|
|
81
78
|
React.createElement(DialogContent, { className: classes.minWidth },
|
|
82
|
-
React.createElement(Accordion, { expanded: expanded === 'shareLinkAccordion', onChange: () =>
|
|
79
|
+
React.createElement(Accordion, { expanded: expanded === 'shareLinkAccordion', onChange: () => {
|
|
80
|
+
setExpanded('shareLinkAccordion');
|
|
81
|
+
} },
|
|
83
82
|
React.createElement(AccordionSummary, { expandIcon: React.createElement(ExpandMoreIcon, { className: classes.expandIcon }) },
|
|
84
83
|
React.createElement(Typography, { style: { display: 'flex', alignItems: 'center', gap: '5px' } }, "Import from share link")),
|
|
85
84
|
React.createElement(AccordionDetails, null,
|
|
86
85
|
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 =>
|
|
88
|
-
|
|
86
|
+
React.createElement(TextField, { label: "Enter Share URL", variant: "outlined", fullWidth: true, value: shareLink, onChange: e => {
|
|
87
|
+
setShareLink(e.target.value);
|
|
88
|
+
} }))),
|
|
89
|
+
React.createElement(Accordion, { expanded: expanded === 'fileAccordion', onChange: () => {
|
|
90
|
+
setExpanded('fileAccordion');
|
|
91
|
+
} },
|
|
89
92
|
React.createElement(AccordionSummary, { expandIcon: React.createElement(ExpandMoreIcon, { className: classes.expandIcon }) },
|
|
90
93
|
React.createElement(Typography, null, "Import from file")),
|
|
91
94
|
React.createElement(AccordionDetails, null,
|
|
92
95
|
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 =>
|
|
96
|
+
React.createElement(AssemblySelector, { onChange: val => {
|
|
97
|
+
setSelectedAsm(val);
|
|
98
|
+
}, helperText: 'Select the assembly for BED file.', session: session, selected: selectedAsm }))),
|
|
94
99
|
error ? React.createElement(ErrorMessage, { error: error }) : null),
|
|
95
100
|
React.createElement(DialogActions, null,
|
|
96
101
|
React.createElement(Button, { variant: "contained", color: "secondary", onClick: onClose }, "Cancel"),
|
|
@@ -26,7 +26,8 @@ const ShareBookmarksDialog = observer(function ({ onClose, model, }) {
|
|
|
26
26
|
? model.allBookmarksModel
|
|
27
27
|
: model.sharedBookmarksModel;
|
|
28
28
|
useEffect(() => {
|
|
29
|
-
|
|
29
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
30
|
+
;
|
|
30
31
|
(async () => {
|
|
31
32
|
try {
|
|
32
33
|
if (!isSessionWithShareURL(session)) {
|
|
@@ -36,14 +37,12 @@ const ShareBookmarksDialog = observer(function ({ onClose, model, }) {
|
|
|
36
37
|
const snap = getSnapshot(bookmarksToShare);
|
|
37
38
|
const locationUrl = new URL(window.location.href);
|
|
38
39
|
const result = await shareSessionToDynamo(snap, session.shareURL, locationUrl.href);
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
setLoading(false);
|
|
46
|
-
}
|
|
40
|
+
const params = new URLSearchParams(locationUrl.search);
|
|
41
|
+
params.set('bookmarks', `share-${result.json.sessionId}`);
|
|
42
|
+
params.set('password', result.password);
|
|
43
|
+
locationUrl.search = params.toString();
|
|
44
|
+
setUrl(locationUrl.href);
|
|
45
|
+
setLoading(false);
|
|
47
46
|
}
|
|
48
47
|
catch (e) {
|
|
49
48
|
setError(e);
|
|
@@ -52,9 +51,6 @@ const ShareBookmarksDialog = observer(function ({ onClose, model, }) {
|
|
|
52
51
|
setLoading(false);
|
|
53
52
|
}
|
|
54
53
|
})();
|
|
55
|
-
return () => {
|
|
56
|
-
cancelled = true;
|
|
57
|
-
};
|
|
58
54
|
}, [bookmarksToShare, session]);
|
|
59
55
|
return (React.createElement(Dialog, { open: true, onClose: onClose, title: "Share bookmarks" },
|
|
60
56
|
React.createElement(DialogContent, { style: { display: 'flex', flexFlow: 'column', gap: '5px' } },
|
|
@@ -21,8 +21,8 @@ declare const LabeledRegionModel: import("mobx-state-tree").IModelType<{
|
|
|
21
21
|
export interface IExtendedLGV extends LinearGenomeViewModel {
|
|
22
22
|
showBookmarkHighlights: boolean;
|
|
23
23
|
showBookmarkLabels: boolean;
|
|
24
|
-
toggleShowBookmarkHighlights: (arg: boolean) =>
|
|
25
|
-
toggleShowBookmarkLabels: (arg: boolean) =>
|
|
24
|
+
toggleShowBookmarkHighlights: (arg: boolean) => void;
|
|
25
|
+
toggleShowBookmarkLabels: (arg: boolean) => void;
|
|
26
26
|
}
|
|
27
27
|
export interface ILabeledRegionModel extends SnapshotIn<typeof LabeledRegionModel> {
|
|
28
28
|
refName: string;
|
|
@@ -158,7 +158,9 @@ export default function f(_pluginManager) {
|
|
|
158
158
|
* #action
|
|
159
159
|
*/
|
|
160
160
|
updateBulkBookmarkHighlights(color) {
|
|
161
|
-
self.selectedBookmarks.forEach(bookmark =>
|
|
161
|
+
self.selectedBookmarks.forEach(bookmark => {
|
|
162
|
+
this.updateBookmarkHighlight(bookmark, color);
|
|
163
|
+
});
|
|
162
164
|
},
|
|
163
165
|
/**
|
|
164
166
|
* #action
|
|
@@ -179,6 +181,7 @@ export default function f(_pluginManager) {
|
|
|
179
181
|
const { views } = getSession(self);
|
|
180
182
|
views.forEach(view => {
|
|
181
183
|
var _a;
|
|
184
|
+
// @ts-expect-error
|
|
182
185
|
(_a = view.toggleShowBookmarkHighlights) === null || _a === void 0 ? void 0 : _a.call(view, toggle);
|
|
183
186
|
});
|
|
184
187
|
},
|
|
@@ -189,6 +192,7 @@ export default function f(_pluginManager) {
|
|
|
189
192
|
const { views } = getSession(self);
|
|
190
193
|
views.forEach(view => {
|
|
191
194
|
var _a;
|
|
195
|
+
// @ts-expect-error
|
|
192
196
|
(_a = view.toggleShowBookmarkLabels) === null || _a === void 0 ? void 0 : _a.call(view, toggle);
|
|
193
197
|
});
|
|
194
198
|
},
|
|
@@ -38,9 +38,12 @@ export function downloadBookmarkFile(fileFormat, model) {
|
|
|
38
38
|
const { label } = bookmark;
|
|
39
39
|
const labelVal = label === '' ? '.' : label;
|
|
40
40
|
const line = `${bookmark.refName}\t${bookmark.start}\t${bookmark.end}\t${labelVal}\n`;
|
|
41
|
-
fileContents[bookmark.assemblyName]
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
if (fileContents[bookmark.assemblyName]) {
|
|
42
|
+
fileContents[bookmark.assemblyName].push(line);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
fileContents[bookmark.assemblyName] = [line];
|
|
46
|
+
}
|
|
44
47
|
});
|
|
45
48
|
for (const assembly in fileContents) {
|
|
46
49
|
const fileContent = fileContents[assembly].reduce((a, b) => a + b, fileHeader);
|
package/esm/index.js
CHANGED
|
@@ -62,9 +62,8 @@ export default class GridBookmarkPlugin extends Plugin {
|
|
|
62
62
|
navigateNewestBookmark() {
|
|
63
63
|
const session = getSession(self);
|
|
64
64
|
const bookmarkWidget = self.activateBookmarkWidget();
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
self.navTo(regions.at(-1));
|
|
65
|
+
if (bookmarkWidget.bookmarks.length) {
|
|
66
|
+
self.navTo(bookmarkWidget.bookmarks.at(-1));
|
|
68
67
|
}
|
|
69
68
|
else {
|
|
70
69
|
session.notify('There are no recent bookmarks to navigate to.', 'info');
|
|
@@ -74,7 +73,12 @@ export default class GridBookmarkPlugin extends Plugin {
|
|
|
74
73
|
if (self.id === getSession(self).focusedViewId) {
|
|
75
74
|
const selectedRegions = self.getSelectedRegions(undefined, undefined);
|
|
76
75
|
const bookmarkWidget = self.activateBookmarkWidget();
|
|
77
|
-
|
|
76
|
+
if (!selectedRegions.length) {
|
|
77
|
+
throw new Error('no region selected');
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
bookmarkWidget.addBookmark(selectedRegions[0]);
|
|
81
|
+
}
|
|
78
82
|
}
|
|
79
83
|
},
|
|
80
84
|
}))
|
|
@@ -98,21 +102,27 @@ export default class GridBookmarkPlugin extends Plugin {
|
|
|
98
102
|
{
|
|
99
103
|
label: 'Bookmark current region',
|
|
100
104
|
icon: BookmarkIcon,
|
|
101
|
-
onClick: () =>
|
|
105
|
+
onClick: () => {
|
|
106
|
+
self.bookmarkCurrentRegion();
|
|
107
|
+
},
|
|
102
108
|
},
|
|
103
109
|
{
|
|
104
110
|
label: 'Toggle bookmark highlights',
|
|
105
111
|
icon: HighlightIcon,
|
|
106
112
|
type: 'checkbox',
|
|
107
113
|
checked: self.showBookmarkHighlights,
|
|
108
|
-
onClick: () =>
|
|
114
|
+
onClick: () => {
|
|
115
|
+
self.toggleShowBookmarkHighlights();
|
|
116
|
+
},
|
|
109
117
|
},
|
|
110
118
|
{
|
|
111
119
|
label: 'Toggle bookmark labels',
|
|
112
120
|
icon: LabelIcon,
|
|
113
121
|
type: 'checkbox',
|
|
114
122
|
checked: self.showBookmarkLabels,
|
|
115
|
-
onClick: () =>
|
|
123
|
+
onClick: () => {
|
|
124
|
+
self.toggleShowBookmarkLabels();
|
|
125
|
+
},
|
|
116
126
|
},
|
|
117
127
|
],
|
|
118
128
|
},
|
|
@@ -128,7 +138,12 @@ export default class GridBookmarkPlugin extends Plugin {
|
|
|
128
138
|
const { leftOffset, rightOffset } = self;
|
|
129
139
|
const selectedRegions = self.getSelectedRegions(leftOffset, rightOffset);
|
|
130
140
|
const bookmarkWidget = self.activateBookmarkWidget();
|
|
131
|
-
|
|
141
|
+
if (!selectedRegions.length) {
|
|
142
|
+
throw new Error('no regions selected');
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
bookmarkWidget.addBookmark(selectedRegions[0]);
|
|
146
|
+
}
|
|
132
147
|
},
|
|
133
148
|
},
|
|
134
149
|
];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jbrowse/plugin-grid-bookmark",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.14.0",
|
|
4
4
|
"description": "JBrowse 2 grid bookmark widget",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jbrowse",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
],
|
|
25
25
|
"scripts": {
|
|
26
26
|
"build": "npm-run-all build:*",
|
|
27
|
-
"test": "cd ../..; jest plugins/grid-bookmark",
|
|
27
|
+
"test": "cd ../..; jest --passWithNoTests plugins/grid-bookmark",
|
|
28
28
|
"prepublishOnly": "yarn test",
|
|
29
29
|
"prepack": "yarn build && yarn useDist",
|
|
30
30
|
"postpack": "yarn useSrc",
|
|
@@ -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": "9fb8231d932db40adf0a283081765431756c66ff"
|
|
63
63
|
}
|