@jbrowse/plugin-grid-bookmark 2.6.3 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/dist/GridBookmarkWidget/components/AssemblySelector.d.ts +3 -4
  2. package/dist/GridBookmarkWidget/components/AssemblySelector.js +27 -37
  3. package/dist/GridBookmarkWidget/components/BookmarkGrid.d.ts +6 -0
  4. package/dist/GridBookmarkWidget/components/BookmarkGrid.js +120 -0
  5. package/dist/GridBookmarkWidget/components/{ClearBookmarks.d.ts → DeleteBookmarks.d.ts} +2 -3
  6. package/dist/GridBookmarkWidget/components/DeleteBookmarks.js +41 -0
  7. package/dist/GridBookmarkWidget/components/DeleteBookmarksDialog.d.ts +7 -0
  8. package/dist/GridBookmarkWidget/components/DeleteBookmarksDialog.js +29 -0
  9. package/dist/GridBookmarkWidget/components/EditBookmarkLabelDialog.d.ts +8 -0
  10. package/dist/GridBookmarkWidget/components/EditBookmarkLabelDialog.js +50 -0
  11. package/dist/GridBookmarkWidget/components/ExportBookmarks.d.ts +6 -0
  12. package/dist/GridBookmarkWidget/components/{ClearBookmarks.js → ExportBookmarks.js} +9 -19
  13. package/dist/GridBookmarkWidget/components/ExportBookmarksDialog.d.ts +7 -0
  14. package/dist/GridBookmarkWidget/components/{DownloadBookmarks.js → ExportBookmarksDialog.js} +22 -20
  15. package/dist/GridBookmarkWidget/components/GridBookmarkWidget.d.ts +3 -4
  16. package/dist/GridBookmarkWidget/components/GridBookmarkWidget.js +28 -102
  17. package/dist/GridBookmarkWidget/components/ImportBookmarks.d.ts +3 -5
  18. package/dist/GridBookmarkWidget/components/ImportBookmarks.js +8 -64
  19. package/dist/GridBookmarkWidget/components/ImportBookmarksDialog.d.ts +7 -0
  20. package/dist/GridBookmarkWidget/components/ImportBookmarksDialog.js +129 -0
  21. package/{esm/GridBookmarkWidget/components/ClearBookmarks.d.ts → dist/GridBookmarkWidget/components/ShareBookmarks.d.ts} +2 -3
  22. package/dist/GridBookmarkWidget/components/ShareBookmarks.js +37 -0
  23. package/dist/GridBookmarkWidget/components/ShareBookmarksDialog.d.ts +7 -0
  24. package/dist/GridBookmarkWidget/components/ShareBookmarksDialog.js +106 -0
  25. package/dist/GridBookmarkWidget/model.d.ts +178 -11
  26. package/dist/GridBookmarkWidget/model.js +105 -27
  27. package/dist/GridBookmarkWidget/sessionSharing.d.ts +6 -0
  28. package/dist/GridBookmarkWidget/sessionSharing.js +96 -0
  29. package/dist/GridBookmarkWidget/utils.d.ts +19 -3
  30. package/dist/GridBookmarkWidget/utils.js +132 -40
  31. package/dist/index.d.ts +1 -1
  32. package/dist/index.js +100 -75
  33. package/esm/GridBookmarkWidget/components/AssemblySelector.d.ts +3 -4
  34. package/esm/GridBookmarkWidget/components/AssemblySelector.js +28 -38
  35. package/esm/GridBookmarkWidget/components/BookmarkGrid.d.ts +6 -0
  36. package/esm/GridBookmarkWidget/components/BookmarkGrid.js +92 -0
  37. package/{dist/GridBookmarkWidget/components/DownloadBookmarks.d.ts → esm/GridBookmarkWidget/components/DeleteBookmarks.d.ts} +2 -3
  38. package/esm/GridBookmarkWidget/components/DeleteBookmarks.js +13 -0
  39. package/esm/GridBookmarkWidget/components/DeleteBookmarksDialog.d.ts +7 -0
  40. package/esm/GridBookmarkWidget/components/DeleteBookmarksDialog.js +24 -0
  41. package/esm/GridBookmarkWidget/components/EditBookmarkLabelDialog.d.ts +8 -0
  42. package/esm/GridBookmarkWidget/components/EditBookmarkLabelDialog.js +25 -0
  43. package/esm/GridBookmarkWidget/components/ExportBookmarks.d.ts +6 -0
  44. package/esm/GridBookmarkWidget/components/ExportBookmarks.js +13 -0
  45. package/esm/GridBookmarkWidget/components/ExportBookmarksDialog.d.ts +7 -0
  46. package/esm/GridBookmarkWidget/components/ExportBookmarksDialog.js +35 -0
  47. package/esm/GridBookmarkWidget/components/GridBookmarkWidget.d.ts +3 -4
  48. package/esm/GridBookmarkWidget/components/GridBookmarkWidget.js +28 -79
  49. package/esm/GridBookmarkWidget/components/ImportBookmarks.d.ts +3 -5
  50. package/esm/GridBookmarkWidget/components/ImportBookmarks.js +10 -66
  51. package/esm/GridBookmarkWidget/components/ImportBookmarksDialog.d.ts +7 -0
  52. package/esm/GridBookmarkWidget/components/ImportBookmarksDialog.js +101 -0
  53. package/esm/GridBookmarkWidget/components/{DownloadBookmarks.d.ts → ShareBookmarks.d.ts} +2 -3
  54. package/esm/GridBookmarkWidget/components/ShareBookmarks.js +12 -0
  55. package/esm/GridBookmarkWidget/components/ShareBookmarksDialog.d.ts +7 -0
  56. package/esm/GridBookmarkWidget/components/ShareBookmarksDialog.js +78 -0
  57. package/esm/GridBookmarkWidget/model.d.ts +178 -11
  58. package/esm/GridBookmarkWidget/model.js +106 -28
  59. package/esm/GridBookmarkWidget/sessionSharing.d.ts +6 -0
  60. package/esm/GridBookmarkWidget/sessionSharing.js +68 -0
  61. package/esm/GridBookmarkWidget/utils.d.ts +19 -3
  62. package/esm/GridBookmarkWidget/utils.js +105 -39
  63. package/esm/index.d.ts +1 -1
  64. package/esm/index.js +101 -76
  65. package/package.json +4 -3
  66. package/dist/GridBookmarkWidget/components/DeleteBookmark.d.ts +0 -9
  67. package/dist/GridBookmarkWidget/components/DeleteBookmark.js +0 -31
  68. package/esm/GridBookmarkWidget/components/ClearBookmarks.js +0 -23
  69. package/esm/GridBookmarkWidget/components/DeleteBookmark.d.ts +0 -9
  70. package/esm/GridBookmarkWidget/components/DeleteBookmark.js +0 -26
  71. package/esm/GridBookmarkWidget/components/DownloadBookmarks.js +0 -33
package/dist/index.js CHANGED
@@ -19,92 +19,117 @@ class default_1 extends Plugin_1.default {
19
19
  pluginManager.addToExtensionPoint('Core-extendPluggableElement', (pluggableElement) => {
20
20
  if (pluggableElement.name === 'LinearGenomeView') {
21
21
  const { stateModel } = pluggableElement;
22
- const newStateModel = stateModel.extend((self) => {
22
+ const lgv = stateModel;
23
+ const newStateModel = lgv
24
+ .actions(self => ({
25
+ activateBookmarkWidget() {
26
+ const session = (0, util_1.getSession)(self);
27
+ if ((0, util_1.isSessionModelWithWidgets)(session)) {
28
+ let bookmarkWidget = session.widgets.get('GridBookmark');
29
+ if (!bookmarkWidget) {
30
+ bookmarkWidget = session.addWidget('GridBookmarkWidget', 'GridBookmark');
31
+ }
32
+ session.showWidget(bookmarkWidget);
33
+ return session.widgets.get('GridBookmark');
34
+ }
35
+ throw new Error('Could not open bookmark widget');
36
+ },
37
+ }))
38
+ .actions(self => ({
39
+ navigateNewestBookmark() {
40
+ const session = (0, util_1.getSession)(self);
41
+ const bookmarkWidget = self.activateBookmarkWidget();
42
+ const regions = bookmarkWidget.bookmarks;
43
+ if (regions === null || regions === void 0 ? void 0 : regions.length) {
44
+ self.navTo(regions.at(-1));
45
+ }
46
+ else {
47
+ session.notify('There are no recent bookmarks to navigate to.', 'info');
48
+ }
49
+ },
50
+ bookmarkCurrentRegion() {
51
+ if (self.id === (0, util_1.getSession)(self).focusedViewId) {
52
+ const selectedRegions = self.getSelectedRegions(undefined, undefined);
53
+ const bookmarkWidget = self.activateBookmarkWidget();
54
+ bookmarkWidget.addBookmark(selectedRegions[0]);
55
+ }
56
+ },
57
+ }))
58
+ .views(self => {
23
59
  const superMenuItems = self.menuItems;
24
60
  const superRubberBandMenuItems = self.rubberBandMenuItems;
25
61
  return {
26
- actions: {
27
- activateBookmarkWidget() {
28
- const session = (0, util_1.getSession)(self);
29
- if ((0, util_1.isSessionModelWithWidgets)(session)) {
30
- let bookmarkWidget = session.widgets.get('GridBookmark');
31
- if (!bookmarkWidget) {
32
- bookmarkWidget = session.addWidget('GridBookmarkWidget', 'GridBookmark', { view: self });
33
- }
34
- session.showWidget(bookmarkWidget);
35
- return bookmarkWidget;
36
- }
37
- throw new Error('Could not open bookmark widget');
38
- },
39
- bookmarkCurrentRegion() {
40
- const selectedRegions = self.getSelectedRegions(self.leftOffset, self.rightOffset);
41
- const firstRegion = selectedRegions[0];
42
- const session = (0, util_1.getSession)(self);
43
- if ((0, util_1.isSessionModelWithWidgets)(session)) {
44
- const { widgets } = session;
45
- let bookmarkWidget = widgets.get('GridBookmark');
46
- if (!bookmarkWidget) {
47
- this.activateBookmarkWidget();
48
- bookmarkWidget = widgets.get('GridBookmark');
49
- }
50
- // @ts-expect-error
51
- bookmarkWidget.addBookmark(firstRegion);
52
- }
53
- },
62
+ menuItems() {
63
+ return [
64
+ ...superMenuItems(),
65
+ { type: 'divider' },
66
+ {
67
+ label: 'Open bookmark widget',
68
+ icon: Bookmarks_1.default,
69
+ onClick: () => self.activateBookmarkWidget(),
70
+ },
71
+ {
72
+ label: 'Bookmark current region',
73
+ icon: Bookmark_1.default,
74
+ onClick: () => self.bookmarkCurrentRegion(),
75
+ },
76
+ ];
54
77
  },
55
- views: {
56
- menuItems() {
57
- return [
58
- ...superMenuItems(),
59
- { type: 'divider' },
60
- {
61
- label: 'Open bookmark widget',
62
- icon: Bookmarks_1.default,
63
- // @ts-expect-error
64
- onClick: self.activateBookmarkWidget,
78
+ rubberBandMenuItems() {
79
+ return [
80
+ ...superRubberBandMenuItems(),
81
+ {
82
+ label: 'Bookmark region',
83
+ icon: Bookmark_1.default,
84
+ onClick: () => {
85
+ const { leftOffset, rightOffset } = self;
86
+ const selectedRegions = self.getSelectedRegions(leftOffset, rightOffset);
87
+ const bookmarkWidget = self.activateBookmarkWidget();
88
+ bookmarkWidget.addBookmark(selectedRegions[0]);
65
89
  },
66
- {
67
- label: 'Bookmark current region',
68
- icon: Bookmark_1.default,
69
- // @ts-expect-error
70
- onClick: self.bookmarkCurrentRegion,
71
- },
72
- ];
73
- },
74
- rubberBandMenuItems() {
75
- return [
76
- ...superRubberBandMenuItems(),
77
- {
78
- label: 'Bookmark region',
79
- icon: Bookmark_1.default,
80
- onClick: () => {
81
- const { leftOffset, rightOffset } = self;
82
- const selectedRegions = self.getSelectedRegions(leftOffset, rightOffset);
83
- const firstRegion = selectedRegions[0];
84
- const session = (0, util_1.getSession)(self);
85
- if ((0, util_1.isSessionModelWithWidgets)(session)) {
86
- const { widgets } = session;
87
- let bookmarkWidget = widgets.get('GridBookmark');
88
- if (!bookmarkWidget) {
89
- // @ts-expect-error
90
- self.activateBookmarkWidget();
91
- bookmarkWidget = widgets.get('GridBookmark');
92
- }
93
- // @ts-expect-error
94
- bookmarkWidget.addBookmark(firstRegion);
95
- }
96
- },
97
- },
98
- ];
99
- },
90
+ },
91
+ ];
100
92
  },
101
93
  };
102
- });
94
+ })
95
+ .actions(self => ({
96
+ afterCreate() {
97
+ document.addEventListener('keydown', e => {
98
+ const activationSequence = (e.ctrlKey || e.metaKey) && e.shiftKey;
99
+ // ctrl+shift+d or cmd+shift+d
100
+ if (activationSequence && e.code === 'KeyD') {
101
+ e.preventDefault();
102
+ self.activateBookmarkWidget();
103
+ self.bookmarkCurrentRegion();
104
+ (0, util_1.getSession)(self).notify('Bookmark created.', 'success');
105
+ }
106
+ // ctrl+shift+m or cmd+shift+m
107
+ if (activationSequence && e.code === 'KeyM') {
108
+ e.preventDefault();
109
+ self.navigateNewestBookmark();
110
+ }
111
+ });
112
+ },
113
+ }));
103
114
  pluggableElement.stateModel = newStateModel;
104
115
  }
105
116
  return pluggableElement;
106
117
  });
107
118
  }
108
- configure(_pluginManager) { }
119
+ configure(pluginManager) {
120
+ if ((0, util_1.isAbstractMenuManager)(pluginManager.rootModel)) {
121
+ pluginManager.rootModel.appendToMenu('Tools', {
122
+ label: 'Bookmarks',
123
+ icon: Bookmarks_1.default,
124
+ onClick: (session) => {
125
+ let bookmarkWidget = session.widgets.get('GridBookmark');
126
+ if (!bookmarkWidget) {
127
+ bookmarkWidget = session.addWidget('GridBookmarkWidget', 'GridBookmark');
128
+ }
129
+ session.showWidget(bookmarkWidget);
130
+ },
131
+ });
132
+ }
133
+ }
109
134
  }
110
135
  exports.default = default_1;
@@ -1,7 +1,6 @@
1
1
  import React from 'react';
2
2
  import { GridBookmarkModel } from '../model';
3
- declare function AssemblySelector({ model }: {
3
+ declare const AssemblySelector: ({ model, }: {
4
4
  model: GridBookmarkModel;
5
- }): React.JSX.Element;
6
- declare const _default: typeof AssemblySelector;
7
- export default _default;
5
+ }) => React.JSX.Element;
6
+ export default AssemblySelector;
@@ -1,40 +1,30 @@
1
1
  import React from 'react';
2
2
  import { observer } from 'mobx-react';
3
- import { Typography, Select, MenuItem, FormControl } from '@mui/material';
4
- import { makeStyles } from 'tss-react/mui';
5
- const useStyles = makeStyles()(() => ({
6
- container: {
7
- display: 'flex',
8
- flexDirection: 'row',
9
- margin: 5,
10
- },
11
- selectText: {
12
- marginRight: 8,
13
- marginTop: 10,
14
- },
15
- flexItem: {
16
- marginRight: 8,
17
- },
18
- }));
19
- function AssemblySelector({ model }) {
20
- const { classes } = useStyles();
21
- const { assemblies, selectedAssembly, setSelectedAssembly } = model;
22
- const noAssemblies = assemblies.length === 0 ? true : false;
23
- const determineCurrentValue = (selectedAssembly) => {
24
- if (selectedAssembly === 'all') {
25
- return 'all';
26
- }
27
- else if (assemblies.includes(selectedAssembly)) {
28
- return selectedAssembly;
29
- }
30
- return 'none';
31
- };
32
- return (React.createElement("div", { className: classes.container },
33
- React.createElement(Typography, { className: classes.selectText }, "Select assembly:"),
34
- React.createElement(FormControl, { className: classes.flexItem, disabled: noAssemblies },
35
- React.createElement(Select, { value: determineCurrentValue(selectedAssembly), onChange: event => setSelectedAssembly(event.target.value) },
36
- React.createElement(MenuItem, { value: "none" }, "none"),
37
- React.createElement(MenuItem, { value: "all" }, "all"),
38
- assemblies.map(assembly => (React.createElement(MenuItem, { value: assembly, key: assembly }, assembly)))))));
39
- }
40
- export default observer(AssemblySelector);
3
+ import { Checkbox, FormControl, InputLabel, ListItemText, MenuItem, OutlinedInput, Select, } from '@mui/material';
4
+ const AssemblySelector = observer(function ({ model, }) {
5
+ const { validAssemblies, selectedAssemblies } = model;
6
+ const noAssemblies = validAssemblies.size === 0 ? true : false;
7
+ const label = 'Select assemblies';
8
+ const id = 'select-assemblies-label';
9
+ const selectedSet = new Set(selectedAssemblies);
10
+ const isAllSelected = [...validAssemblies].every(e => selectedSet.has(e));
11
+ return (React.createElement(FormControl, { disabled: noAssemblies, fullWidth: true },
12
+ React.createElement(InputLabel, { id: id }, label),
13
+ React.createElement(Select, { labelId: id, multiple: true, value: selectedAssemblies, onChange: event => model.setSelectedAssemblies([...event.target.value]), input: React.createElement(OutlinedInput, { label: label }), renderValue: selected => selected.join(', ') },
14
+ React.createElement(MenuItem, { onClickCapture: event => {
15
+ // onClickCapture allows us to avoid the parent Select onChange from triggering
16
+ if (isAllSelected) {
17
+ model.setSelectedAssemblies([]);
18
+ }
19
+ else {
20
+ model.setSelectedAssemblies(undefined);
21
+ }
22
+ event.preventDefault();
23
+ } },
24
+ React.createElement(Checkbox, { checked: isAllSelected, indeterminate: !isAllSelected && selectedAssemblies.length > 0 }),
25
+ React.createElement(ListItemText, { primary: "Select all" })),
26
+ [...validAssemblies].map(name => (React.createElement(MenuItem, { key: name, value: name },
27
+ React.createElement(Checkbox, { checked: selectedAssemblies.includes(name) }),
28
+ React.createElement(ListItemText, { primary: name })))))));
29
+ });
30
+ export default AssemblySelector;
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import { GridBookmarkModel } from '../model';
3
+ declare const BookmarkGrid: ({ model, }: {
4
+ model: GridBookmarkModel;
5
+ }) => React.JSX.Element;
6
+ export default BookmarkGrid;
@@ -0,0 +1,92 @@
1
+ import React, { Suspense, lazy, useState } from 'react';
2
+ import { observer } from 'mobx-react';
3
+ import { Link } from '@mui/material';
4
+ import { makeStyles } from 'tss-react/mui';
5
+ import { DataGrid, GRID_CHECKBOX_SELECTION_COL_DEF } from '@mui/x-data-grid';
6
+ import { getSession, assembleLocString, measureGridWidth, measureText, } from '@jbrowse/core/util';
7
+ // locals
8
+ import { navToBookmark } from '../utils';
9
+ import { useResizeBar } from '@jbrowse/core/ui/useResizeBar';
10
+ import ResizeBar from '@jbrowse/core/ui/ResizeBar';
11
+ const EditBookmarkLabelDialog = lazy(() => import('./EditBookmarkLabelDialog'));
12
+ const useStyles = makeStyles()(() => ({
13
+ link: {
14
+ cursor: 'pointer',
15
+ },
16
+ cell: {
17
+ whiteSpace: 'nowrap',
18
+ overflow: 'hidden',
19
+ textOverflow: 'ellipsis',
20
+ },
21
+ }));
22
+ const BookmarkGrid = observer(function ({ model, }) {
23
+ const { classes, cx } = useStyles();
24
+ const [dialogRow, setDialogRow] = useState();
25
+ const { ref, scrollLeft } = useResizeBar();
26
+ const { bookmarks, bookmarksWithValidAssemblies, selectedAssemblies, selectedBookmarks, } = model;
27
+ const session = getSession(model);
28
+ const selectedSet = new Set(selectedAssemblies);
29
+ const rows = bookmarks
30
+ .filter(r => selectedSet.has(r.assemblyName))
31
+ .map((region, index) => {
32
+ const { assemblyName, ...rest } = region;
33
+ return {
34
+ ...region,
35
+ id: index,
36
+ assemblyName,
37
+ locString: assembleLocString(rest),
38
+ correspondingObj: region,
39
+ };
40
+ });
41
+ // reset selections if bookmarked regions change
42
+ // needed especially if bookmarked regions are deleted, then
43
+ const [widths, setWidths] = useState([
44
+ 40,
45
+ Math.max(measureText('Bookmark link'), measureGridWidth(rows.map(row => row.locString))),
46
+ Math.max(measureText('Label'), measureGridWidth(rows.map(row => row.label))),
47
+ Math.max(measureText('Assembly'), measureGridWidth(rows.map(row => row.assemblyName))),
48
+ ]);
49
+ return (React.createElement(React.Fragment, null,
50
+ React.createElement("div", { ref: ref },
51
+ React.createElement(ResizeBar, { widths: widths, setWidths: setWidths, scrollLeft: scrollLeft }),
52
+ React.createElement(DataGrid, { autoHeight: true, density: "compact", rows: rows, columns: [
53
+ {
54
+ ...GRID_CHECKBOX_SELECTION_COL_DEF,
55
+ width: widths[0],
56
+ },
57
+ {
58
+ field: 'locString',
59
+ headerName: 'Bookmark link',
60
+ width: widths[1],
61
+ renderCell: ({ value, row }) => (React.createElement(Link, { className: cx(classes.link, classes.cell), href: "#", onClick: async (event) => {
62
+ event.preventDefault();
63
+ const { views } = session;
64
+ await navToBookmark(value, row.assemblyName, views, model);
65
+ } }, value)),
66
+ },
67
+ {
68
+ field: 'label',
69
+ headerName: 'Label',
70
+ width: widths[2],
71
+ editable: true,
72
+ },
73
+ {
74
+ field: 'assemblyName',
75
+ headerName: 'Assembly',
76
+ width: widths[3],
77
+ },
78
+ ], onCellDoubleClick: ({ row }) => setDialogRow(row), processRowUpdate: row => {
79
+ const target = rows[row.id];
80
+ model.updateBookmarkLabel(target, row.label);
81
+ return row;
82
+ }, onProcessRowUpdateError: e => session.notify(e.message, 'error'), checkboxSelection: true, onRowSelectionModelChange: newRowSelectionModel => {
83
+ if (bookmarksWithValidAssemblies.length > 0) {
84
+ model.setSelectedBookmarks(newRowSelectionModel.map(value => ({
85
+ ...rows[value],
86
+ })));
87
+ }
88
+ }, rowSelectionModel: selectedBookmarks.map(r => r.id), disableRowSelectionOnClick: true })),
89
+ dialogRow ? (React.createElement(Suspense, { fallback: React.createElement(React.Fragment, null) },
90
+ React.createElement(EditBookmarkLabelDialog, { onClose: () => setDialogRow(undefined), model: model, dialogRow: dialogRow }))) : null));
91
+ });
92
+ export default BookmarkGrid;
@@ -1,7 +1,6 @@
1
1
  import React from 'react';
2
2
  import { GridBookmarkModel } from '../model';
3
- declare function DownloadBookmarks({ model }: {
3
+ declare function DeleteBookmarks({ model }: {
4
4
  model: GridBookmarkModel;
5
5
  }): React.JSX.Element;
6
- declare const _default: typeof DownloadBookmarks;
7
- export default _default;
6
+ export default DeleteBookmarks;
@@ -0,0 +1,13 @@
1
+ import React, { Suspense, lazy, useState } from 'react';
2
+ import { Button } from '@mui/material';
3
+ // icons
4
+ import DeleteIcon from '@mui/icons-material/Delete';
5
+ const DeleteBookmarksDialog = lazy(() => import('./DeleteBookmarksDialog'));
6
+ function DeleteBookmarks({ model }) {
7
+ const [open, setOpen] = useState(false);
8
+ return (React.createElement(React.Fragment, null,
9
+ React.createElement(Button, { startIcon: React.createElement(DeleteIcon, null), "aria-label": "clear bookmarks", onClick: () => setOpen(true) }, "Delete"),
10
+ open ? (React.createElement(Suspense, { fallback: React.createElement(React.Fragment, null) },
11
+ React.createElement(DeleteBookmarksDialog, { model: model, onClose: () => setOpen(false) }))) : null));
12
+ }
13
+ export default DeleteBookmarks;
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ import { GridBookmarkModel } from '../model';
3
+ declare const DeleteBookmarksDialog: ({ onClose, model, }: {
4
+ onClose: () => void;
5
+ model: GridBookmarkModel;
6
+ }) => React.JSX.Element;
7
+ export default DeleteBookmarksDialog;
@@ -0,0 +1,24 @@
1
+ import React from 'react';
2
+ import { observer } from 'mobx-react';
3
+ import { Button, DialogContent, DialogActions, Alert } from '@mui/material';
4
+ import { Dialog } from '@jbrowse/core/ui';
5
+ const DeleteBookmarksDialog = observer(function ({ onClose, model, }) {
6
+ const { selectedBookmarks } = model;
7
+ const deleteAll = selectedBookmarks.length === 0;
8
+ return (React.createElement(Dialog, { open: true, onClose: onClose, title: "Delete bookmarks" },
9
+ React.createElement(DialogContent, null,
10
+ React.createElement(Alert, { severity: "warning" }, deleteAll ? (React.createElement(React.Fragment, null,
11
+ React.createElement("span", null, "All bookmarks will be deleted."),
12
+ React.createElement("br", null),
13
+ React.createElement("span", null, "Use the checkboxes to select individual bookmarks to delete."))) : ('Only selected bookmarks will be deleted.'))),
14
+ React.createElement(DialogActions, null,
15
+ React.createElement(Button, { variant: "contained", color: "secondary", onClick: () => onClose() }, "Cancel"),
16
+ React.createElement(Button, { variant: "contained", color: "primary", onClick: () => {
17
+ if (deleteAll) {
18
+ model.clearAllBookmarks();
19
+ }
20
+ model.clearSelectedBookmarks();
21
+ onClose();
22
+ } }, "Confirm"))));
23
+ });
24
+ export default DeleteBookmarksDialog;
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import { GridBookmarkModel, IExtendedLabeledRegionModel } from '../model';
3
+ declare const EditBookmarkLabelDialog: ({ model, onClose, dialogRow, }: {
4
+ model: GridBookmarkModel;
5
+ dialogRow: IExtendedLabeledRegionModel;
6
+ onClose: () => void;
7
+ }) => React.JSX.Element;
8
+ export default EditBookmarkLabelDialog;
@@ -0,0 +1,25 @@
1
+ import React, { useState } from 'react';
2
+ import { Alert, DialogContent, DialogActions, Button, TextField, } from '@mui/material';
3
+ import { Dialog } from '@jbrowse/core/ui';
4
+ import { observer } from 'mobx-react';
5
+ import { assembleLocString } from '@jbrowse/core/util';
6
+ const EditBookmarkLabelDialog = observer(function ({ model, onClose, dialogRow, }) {
7
+ const [newLabel, setNewLabel] = useState(dialogRow.label || '');
8
+ return (React.createElement(Dialog, { open: true, onClose: onClose, title: "Edit bookmark label" },
9
+ React.createElement(DialogContent, null,
10
+ React.createElement(Alert, null,
11
+ "Editing label for bookmark",
12
+ ' ',
13
+ React.createElement("strong", null, assembleLocString(dialogRow.correspondingObj)),
14
+ ":"),
15
+ React.createElement(TextField, { fullWidth: true, inputProps: { 'data-testid': 'edit-bookmark-label-field' }, variant: "outlined", value: newLabel, onChange: e => setNewLabel(e.target.value), autoFocus: true })),
16
+ React.createElement(DialogActions, null,
17
+ React.createElement(Button, { variant: "contained", color: "primary", onClick: () => {
18
+ if (newLabel && dialogRow) {
19
+ model.updateBookmarkLabel(dialogRow, newLabel);
20
+ }
21
+ setNewLabel('');
22
+ onClose();
23
+ } }, "Confirm"))));
24
+ });
25
+ export default EditBookmarkLabelDialog;
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import { GridBookmarkModel } from '../model';
3
+ declare const ExportBookmarks: ({ model, }: {
4
+ model: GridBookmarkModel;
5
+ }) => React.JSX.Element;
6
+ export default ExportBookmarks;
@@ -0,0 +1,13 @@
1
+ import React, { Suspense, lazy, useState } from 'react';
2
+ import { observer } from 'mobx-react';
3
+ import { Button } from '@mui/material';
4
+ import GetAppIcon from '@mui/icons-material/GetApp';
5
+ const ExportBookmarksDialog = lazy(() => import('./ExportBookmarksDialog'));
6
+ const ExportBookmarks = observer(function ExportBookmarks({ model, }) {
7
+ const [open, setOpen] = useState(false);
8
+ return (React.createElement(React.Fragment, null,
9
+ React.createElement(Button, { startIcon: React.createElement(GetAppIcon, null), onClick: () => setOpen(true), "data-testid": "export_button" }, "Export"),
10
+ open ? (React.createElement(Suspense, { fallback: React.createElement(React.Fragment, null) },
11
+ React.createElement(ExportBookmarksDialog, { onClose: () => setOpen(false), model: model }))) : null));
12
+ });
13
+ export default ExportBookmarks;
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ import { GridBookmarkModel } from '../model';
3
+ declare const ExportBookmarksDialog: ({ model, onClose, }: {
4
+ model: GridBookmarkModel;
5
+ onClose: (arg: boolean) => void;
6
+ }) => React.JSX.Element;
7
+ export default ExportBookmarksDialog;
@@ -0,0 +1,35 @@
1
+ import React, { useState } from 'react';
2
+ import { observer } from 'mobx-react';
3
+ import { Button, DialogContent, DialogActions, MenuItem, Select, Typography, Alert, } from '@mui/material';
4
+ import GetAppIcon from '@mui/icons-material/GetApp';
5
+ import { makeStyles } from 'tss-react/mui';
6
+ import { Dialog } from '@jbrowse/core/ui';
7
+ import { downloadBookmarkFile } from '../utils';
8
+ const useStyles = makeStyles()(() => ({
9
+ flexItem: {
10
+ margin: 5,
11
+ },
12
+ }));
13
+ const ExportBookmarksDialog = observer(function ExportBookmarksDialog({ model, onClose, }) {
14
+ const { classes } = useStyles();
15
+ const [fileType, setFileType] = useState('BED');
16
+ const { selectedBookmarks } = model;
17
+ const exportAll = selectedBookmarks.length === 0;
18
+ return (React.createElement(Dialog, { open: true, onClose: onClose, title: "Export bookmarks" },
19
+ React.createElement(DialogContent, { style: { display: 'flex', flexFlow: 'column', gap: '5px' } },
20
+ React.createElement(Alert, { severity: "info" }, exportAll ? (React.createElement(React.Fragment, null,
21
+ React.createElement("span", null, "All bookmarks will be exported."),
22
+ React.createElement("br", null),
23
+ React.createElement("span", null, "Use the checkboxes to select individual bookmarks to export."))) : ('Only selected bookmarks will be exported.')),
24
+ React.createElement("div", { style: { display: 'flex', alignItems: 'center' } },
25
+ React.createElement(Typography, null, "Format to download:"),
26
+ React.createElement(Select, { size: "small", className: classes.flexItem, "data-testid": "selectFileType", value: fileType, onChange: event => setFileType(event.target.value) },
27
+ React.createElement(MenuItem, { value: "BED" }, "BED"),
28
+ React.createElement(MenuItem, { value: "TSV" }, "TSV")))),
29
+ React.createElement(DialogActions, null,
30
+ React.createElement(Button, { className: classes.flexItem, "data-testid": "dialogDownload", variant: "contained", color: "primary", startIcon: React.createElement(GetAppIcon, null), onClick: () => {
31
+ downloadBookmarkFile(fileType, model);
32
+ onClose(false);
33
+ } }, "Download"))));
34
+ });
35
+ export default ExportBookmarksDialog;
@@ -1,7 +1,6 @@
1
1
  import React from 'react';
2
2
  import { GridBookmarkModel } from '../model';
3
- declare function GridBookmarkWidget({ model }: {
3
+ declare const GridBookmarkWidget: ({ model, }: {
4
4
  model: GridBookmarkModel;
5
- }): React.JSX.Element;
6
- declare const _default: typeof GridBookmarkWidget;
7
- export default _default;
5
+ }) => React.JSX.Element | null;
6
+ export default GridBookmarkWidget;