@jbrowse/plugin-spreadsheet-view 2.13.1 → 2.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/LaunchSpreadsheetView/index.js +2 -5
- package/dist/SpreadsheetView/components/CellData.d.ts +1 -1
- package/dist/SpreadsheetView/components/ColumnFilterControls.js +1 -4
- package/dist/SpreadsheetView/components/ColumnMenu.js +25 -11
- package/dist/SpreadsheetView/components/DataRow.d.ts +2 -2
- package/dist/SpreadsheetView/components/DataRow.js +1 -1
- package/dist/SpreadsheetView/components/DataTable.d.ts +1 -1
- package/dist/SpreadsheetView/components/DataTableHeader.js +23 -20
- package/dist/SpreadsheetView/components/GlobalFilterControls.js +6 -3
- package/dist/SpreadsheetView/components/ImportWizard.js +16 -6
- package/dist/SpreadsheetView/components/NumberEditor.js +3 -1
- package/dist/SpreadsheetView/components/RowCountMessage.d.ts +3 -4
- package/dist/SpreadsheetView/components/RowCountMessage.js +6 -1
- package/dist/SpreadsheetView/components/RowMenu.d.ts +2 -2
- package/dist/SpreadsheetView/components/RowMenu.js +1 -0
- package/dist/SpreadsheetView/components/Spreadsheet.d.ts +1 -1
- package/dist/SpreadsheetView/components/Spreadsheet.js +3 -2
- package/dist/SpreadsheetView/components/StatusBar.js +12 -9
- package/dist/SpreadsheetView/importAdapters/BedImport.js +2 -3
- package/dist/SpreadsheetView/importAdapters/ImportUtils.js +1 -0
- package/dist/SpreadsheetView/importAdapters/STARFusionImport.js +1 -2
- package/dist/SpreadsheetView/importAdapters/VcfImport.js +4 -2
- package/dist/SpreadsheetView/models/ColumnDataTypes/LocEnd.js +1 -1
- package/dist/SpreadsheetView/models/ColumnDataTypes/LocStart.js +1 -1
- package/dist/SpreadsheetView/models/ColumnDataTypes/LocString.js +3 -11
- package/dist/SpreadsheetView/models/ColumnDataTypes/Number.js +5 -8
- package/dist/SpreadsheetView/models/ColumnDataTypes/Text.js +1 -4
- package/dist/SpreadsheetView/models/FilterControls.js +2 -5
- package/dist/SpreadsheetView/models/ImportWizard.js +0 -7
- package/dist/SpreadsheetView/models/Row.js +0 -2
- package/dist/SpreadsheetView/models/Spreadsheet.d.ts +1 -1
- package/dist/SpreadsheetView/models/Spreadsheet.js +2 -2
- package/dist/SpreadsheetView/models/SpreadsheetView.d.ts +0 -4
- package/dist/SpreadsheetView/models/SpreadsheetView.js +6 -10
- package/dist/SpreadsheetView/models/StaticRowSet.js +3 -6
- package/esm/LaunchSpreadsheetView/index.js +2 -5
- package/esm/SpreadsheetView/components/CellData.d.ts +1 -1
- package/esm/SpreadsheetView/components/ColumnFilterControls.js +1 -4
- package/esm/SpreadsheetView/components/ColumnMenu.js +25 -11
- package/esm/SpreadsheetView/components/DataRow.d.ts +2 -2
- package/esm/SpreadsheetView/components/DataRow.js +1 -1
- package/esm/SpreadsheetView/components/DataTable.d.ts +1 -1
- package/esm/SpreadsheetView/components/DataTableHeader.js +23 -20
- package/esm/SpreadsheetView/components/GlobalFilterControls.js +6 -3
- package/esm/SpreadsheetView/components/ImportWizard.js +16 -6
- package/esm/SpreadsheetView/components/NumberEditor.js +3 -1
- package/esm/SpreadsheetView/components/RowCountMessage.d.ts +3 -4
- package/esm/SpreadsheetView/components/RowCountMessage.js +3 -1
- package/esm/SpreadsheetView/components/RowMenu.d.ts +2 -2
- package/esm/SpreadsheetView/components/RowMenu.js +1 -0
- package/esm/SpreadsheetView/components/Spreadsheet.d.ts +1 -1
- package/esm/SpreadsheetView/components/Spreadsheet.js +3 -2
- package/esm/SpreadsheetView/components/StatusBar.js +12 -9
- package/esm/SpreadsheetView/importAdapters/BedImport.js +2 -3
- package/esm/SpreadsheetView/importAdapters/ImportUtils.js +1 -0
- package/esm/SpreadsheetView/importAdapters/STARFusionImport.js +1 -2
- package/esm/SpreadsheetView/importAdapters/VcfImport.js +4 -2
- package/esm/SpreadsheetView/models/ColumnDataTypes/LocEnd.js +1 -1
- package/esm/SpreadsheetView/models/ColumnDataTypes/LocStart.js +1 -1
- package/esm/SpreadsheetView/models/ColumnDataTypes/LocString.js +3 -11
- package/esm/SpreadsheetView/models/ColumnDataTypes/Number.js +5 -8
- package/esm/SpreadsheetView/models/ColumnDataTypes/Text.js +1 -4
- package/esm/SpreadsheetView/models/ColumnDataTypes/index.js +2 -2
- package/esm/SpreadsheetView/models/FilterControls.js +2 -5
- package/esm/SpreadsheetView/models/ImportWizard.js +0 -7
- package/esm/SpreadsheetView/models/Row.js +0 -2
- package/esm/SpreadsheetView/models/Spreadsheet.d.ts +1 -1
- package/esm/SpreadsheetView/models/Spreadsheet.js +2 -2
- package/esm/SpreadsheetView/models/SpreadsheetView.d.ts +0 -4
- package/esm/SpreadsheetView/models/SpreadsheetView.js +7 -11
- package/esm/SpreadsheetView/models/StaticRowSet.js +3 -6
- package/package.json +6 -6
|
@@ -7,13 +7,10 @@ function LaunchSpreadsheetViewF(pluginManager) {
|
|
|
7
7
|
async ({ session, assembly, uri, fileType, }) => {
|
|
8
8
|
var _a, _b;
|
|
9
9
|
const view = session.addView('SpreadsheetView');
|
|
10
|
-
if (!view) {
|
|
11
|
-
throw new Error('Failed to initialize view');
|
|
12
|
-
}
|
|
13
10
|
const exts = uri.split('.');
|
|
14
|
-
let ext = (_a = exts
|
|
11
|
+
let ext = (_a = exts.pop()) === null || _a === void 0 ? void 0 : _a.toUpperCase();
|
|
15
12
|
if (ext === 'GZ') {
|
|
16
|
-
ext = (_b = exts
|
|
13
|
+
ext = (_b = exts.pop()) === null || _b === void 0 ? void 0 : _b.toUpperCase();
|
|
17
14
|
}
|
|
18
15
|
view.importWizard.setFileType(fileType || ext || '');
|
|
19
16
|
view.importWizard.setSelectedAssemblyName(assembly);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Instance } from 'mobx-state-tree';
|
|
2
|
-
import SpreadsheetStateModel from '../models/Spreadsheet';
|
|
2
|
+
import type SpreadsheetStateModel from '../models/Spreadsheet';
|
|
3
3
|
type SpreadsheetModel = Instance<typeof SpreadsheetStateModel>;
|
|
4
4
|
declare const CellData: ({ cell, spreadsheetModel, columnNumber, }: {
|
|
5
5
|
cell: any;
|
|
@@ -33,7 +33,6 @@ const useStyles = (0, mui_1.makeStyles)()(theme => ({
|
|
|
33
33
|
padding: theme.spacing(1.5),
|
|
34
34
|
},
|
|
35
35
|
}));
|
|
36
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
37
36
|
function FilterOperations({ filterModel }) {
|
|
38
37
|
if (filterModel) {
|
|
39
38
|
return react_1.default.createElement(filterModel.ReactComponent, { filterModel: filterModel });
|
|
@@ -50,9 +49,7 @@ const ColumnFilterControls = (0, mobx_react_1.observer)(function ({ viewModel, f
|
|
|
50
49
|
react_1.default.createElement(material_1.Grid, { item: true, className: classes.filterIconBg },
|
|
51
50
|
react_1.default.createElement(FilterList_1.default, { className: classes.filterIcon })),
|
|
52
51
|
react_1.default.createElement(material_1.Grid, { item: true },
|
|
53
|
-
react_1.default.createElement(material_1.IconButton, { onClick: () =>
|
|
54
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
55
|
-
(0, mobx_state_tree_1.getParent)(filterModel, 2).removeColumnFilter(filterModel), title: "remove filter" },
|
|
52
|
+
react_1.default.createElement(material_1.IconButton, { onClick: () => (0, mobx_state_tree_1.getParent)(filterModel, 2).removeColumnFilter(filterModel), title: "remove filter" },
|
|
56
53
|
react_1.default.createElement(Close_1.default, null)),
|
|
57
54
|
react_1.default.createElement(material_1.Typography, { className: classes.columnName, component: "span" }, columnDefinition.name),
|
|
58
55
|
' ',
|
|
@@ -13,7 +13,9 @@ const FilterList_1 = __importDefault(require("@mui/icons-material/FilterList"));
|
|
|
13
13
|
const PermDataSetting_1 = __importDefault(require("@mui/icons-material/PermDataSetting"));
|
|
14
14
|
const Sort_1 = __importDefault(require("@mui/icons-material/Sort"));
|
|
15
15
|
const ColumnMenu = (0, mobx_react_1.observer)(function ({ viewModel, spreadsheetModel, currentColumnMenu, setColumnMenu, }) {
|
|
16
|
-
const columnMenuClose = () =>
|
|
16
|
+
const columnMenuClose = () => {
|
|
17
|
+
setColumnMenu(undefined);
|
|
18
|
+
};
|
|
17
19
|
const columnNumber = (currentColumnMenu === null || currentColumnMenu === void 0 ? void 0 : currentColumnMenu.colNumber) || 0;
|
|
18
20
|
const sortMenuClick = (descending) => {
|
|
19
21
|
spreadsheetModel.setSortColumns([
|
|
@@ -57,36 +59,46 @@ const ColumnMenu = (0, mobx_react_1.observer)(function ({ viewModel, spreadsheet
|
|
|
57
59
|
icon: Sort_1.default,
|
|
58
60
|
type: 'radio',
|
|
59
61
|
checked: isSortingAscending,
|
|
60
|
-
onClick: () =>
|
|
62
|
+
onClick: () => {
|
|
63
|
+
sortMenuClick(false);
|
|
64
|
+
},
|
|
61
65
|
},
|
|
62
66
|
{
|
|
63
67
|
label: 'Sort descending',
|
|
64
68
|
icon: Sort_1.default,
|
|
65
69
|
type: 'radio',
|
|
66
70
|
checked: isSortingDescending,
|
|
67
|
-
onClick: () =>
|
|
71
|
+
onClick: () => {
|
|
72
|
+
sortMenuClick(true);
|
|
73
|
+
},
|
|
68
74
|
},
|
|
69
75
|
{
|
|
70
76
|
label: 'No sort',
|
|
71
77
|
icon: Sort_1.default,
|
|
72
78
|
type: 'radio',
|
|
73
79
|
checked: !isSortingDescending && !isSortingAscending,
|
|
74
|
-
onClick: () =>
|
|
80
|
+
onClick: () => {
|
|
81
|
+
spreadsheetModel.setSortColumns([]);
|
|
82
|
+
},
|
|
75
83
|
},
|
|
76
84
|
// data type menu
|
|
77
85
|
{
|
|
78
86
|
label: `Type: ${dataTypeDisplayName}`,
|
|
79
87
|
icon: PermDataSetting_1.default,
|
|
80
88
|
subMenu: (0, util_1.iterMap)(dataTypeTopLevelMenu.entries(), ([displayName, record]) => {
|
|
89
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
81
90
|
if ('typeName' in record && record.typeName) {
|
|
82
91
|
const { typeName } = record;
|
|
83
92
|
return {
|
|
84
93
|
label: displayName || typeName,
|
|
85
94
|
icon: dataTypeName === typeName ? Check_1.default : undefined,
|
|
86
|
-
onClick: () =>
|
|
95
|
+
onClick: () => {
|
|
96
|
+
spreadsheetModel.setColumnType(columnNumber, typeName);
|
|
97
|
+
},
|
|
87
98
|
};
|
|
88
99
|
}
|
|
89
|
-
|
|
100
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
101
|
+
if ('subMenuItems' in record && record.subMenuItems) {
|
|
90
102
|
const { subMenuItems } = record;
|
|
91
103
|
return {
|
|
92
104
|
label: displayName,
|
|
@@ -96,13 +108,13 @@ const ColumnMenu = (0, mobx_react_1.observer)(function ({ viewModel, spreadsheet
|
|
|
96
108
|
subMenu: subMenuItems.map(({ typeName, displayName }) => ({
|
|
97
109
|
label: displayName,
|
|
98
110
|
icon: typeName === dataTypeName ? Check_1.default : undefined,
|
|
99
|
-
onClick: () =>
|
|
111
|
+
onClick: () => {
|
|
112
|
+
spreadsheetModel.setColumnType(columnNumber, typeName);
|
|
113
|
+
},
|
|
100
114
|
})),
|
|
101
115
|
};
|
|
102
116
|
}
|
|
103
|
-
|
|
104
|
-
return null;
|
|
105
|
-
}
|
|
117
|
+
return null;
|
|
106
118
|
}).filter(Boolean),
|
|
107
119
|
},
|
|
108
120
|
];
|
|
@@ -112,7 +124,9 @@ const ColumnMenu = (0, mobx_react_1.observer)(function ({ viewModel, spreadsheet
|
|
|
112
124
|
menuItems.push({
|
|
113
125
|
label: 'Create filter',
|
|
114
126
|
icon: FilterList_1.default,
|
|
115
|
-
onClick: () =>
|
|
127
|
+
onClick: () => {
|
|
128
|
+
viewModel.filterControls.addBlankColumnFilter(columnNumber);
|
|
129
|
+
},
|
|
116
130
|
});
|
|
117
131
|
}
|
|
118
132
|
return (react_1.default.createElement(ui_1.Menu, { anchorEl: currentColumnMenu === null || currentColumnMenu === void 0 ? void 0 : currentColumnMenu.anchorEl, open: Boolean(currentColumnMenu), onMenuItemClick: (_event, callback) => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Instance } from 'mobx-state-tree';
|
|
3
|
-
import SpreadsheetStateModel from '../models/Spreadsheet';
|
|
4
|
-
import RowStateModel from '../models/Row';
|
|
3
|
+
import type SpreadsheetStateModel from '../models/Spreadsheet';
|
|
4
|
+
import type RowStateModel from '../models/Row';
|
|
5
5
|
type SpreadsheetModel = Instance<typeof SpreadsheetStateModel>;
|
|
6
6
|
type RowModel = Instance<typeof RowStateModel>;
|
|
7
7
|
declare const DataRow: ({ rowModel, rowNumber, spreadsheetModel, }: {
|
|
@@ -56,7 +56,7 @@ const DataRow = (0, mobx_react_1.observer)(function ({ rowModel, rowNumber, spre
|
|
|
56
56
|
const { hideRowSelection, columnDisplayOrder } = spreadsheetModel;
|
|
57
57
|
let rowClass = '';
|
|
58
58
|
if (rowModel.isSelected) {
|
|
59
|
-
rowClass +=
|
|
59
|
+
rowClass += classes.dataRowSelected;
|
|
60
60
|
}
|
|
61
61
|
function labelClick(evt) {
|
|
62
62
|
rowModel.toggleSelect();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Instance } from 'mobx-state-tree';
|
|
3
|
-
import SpreadsheetStateModel from '../models/Spreadsheet';
|
|
3
|
+
import type SpreadsheetStateModel from '../models/Spreadsheet';
|
|
4
4
|
type SpreadsheetModel = Instance<typeof SpreadsheetStateModel>;
|
|
5
5
|
declare const DataTable: ({ model, page, rowsPerPage, }: {
|
|
6
6
|
model: SpreadsheetModel;
|
|
@@ -74,28 +74,31 @@ const DataTableHeader = (0, mobx_react_1.observer)(function ({ model, }) {
|
|
|
74
74
|
react_1.default.createElement("th", { className: classes.topLeftCorner },
|
|
75
75
|
react_1.default.createElement(material_1.Tooltip, { title: "Unselect all", placement: "right" },
|
|
76
76
|
react_1.default.createElement("span", null,
|
|
77
|
-
react_1.default.createElement(material_1.IconButton, { onClick: () =>
|
|
77
|
+
react_1.default.createElement(material_1.IconButton, { onClick: () => {
|
|
78
|
+
model.unselectAll();
|
|
79
|
+
}, disabled: !rowSet.selectedCount },
|
|
78
80
|
react_1.default.createElement(CropFree_1.default, null))))),
|
|
79
|
-
columnDisplayOrder.map(colNumber => {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
81
|
+
columnDisplayOrder.map(colNumber => (react_1.default.createElement("th", { className: classes.columnHead, key: colNumber, onMouseOver: () => {
|
|
82
|
+
setHoveredColumn(colNumber);
|
|
83
|
+
}, onMouseOut: () => {
|
|
84
|
+
setHoveredColumn(undefined);
|
|
85
|
+
} },
|
|
86
|
+
react_1.default.createElement(SortIndicator_1.default, { model: model, columnNumber: colNumber }),
|
|
87
|
+
(hasColumnNames && columns[colNumber].name) ||
|
|
88
|
+
(0, util_1.numToColName)(colNumber),
|
|
89
|
+
react_1.default.createElement("div", { className: classes.columnButtonContainer, style: {
|
|
90
|
+
display: currentHoveredColumn === colNumber ||
|
|
91
|
+
(currentColumnMenu === null || currentColumnMenu === void 0 ? void 0 : currentColumnMenu.colNumber) === colNumber
|
|
92
|
+
? 'block'
|
|
93
|
+
: 'none',
|
|
94
|
+
} },
|
|
95
|
+
react_1.default.createElement(material_1.IconButton, { onClick: evt => {
|
|
96
|
+
setColumnMenu({
|
|
97
|
+
colNumber,
|
|
98
|
+
anchorEl: evt.currentTarget,
|
|
99
|
+
});
|
|
90
100
|
} },
|
|
91
|
-
react_1.default.createElement(
|
|
92
|
-
setColumnMenu({
|
|
93
|
-
colNumber,
|
|
94
|
-
anchorEl: evt.currentTarget,
|
|
95
|
-
});
|
|
96
|
-
} },
|
|
97
|
-
react_1.default.createElement(ArrowDropDown_1.default, null)))));
|
|
98
|
-
}))),
|
|
101
|
+
react_1.default.createElement(ArrowDropDown_1.default, null)))))))),
|
|
99
102
|
react_1.default.createElement(ColumnMenu_1.default, { viewModel: (0, mobx_state_tree_1.getParent)(model), spreadsheetModel: model, currentColumnMenu: currentColumnMenu, setColumnMenu: setColumnMenu })));
|
|
100
103
|
});
|
|
101
104
|
exports.default = DataTableHeader;
|
|
@@ -47,15 +47,18 @@ const TextFilter = (0, mobx_react_1.observer)(function ({ textFilter, }) {
|
|
|
47
47
|
textFilter.setString(debouncedTextFilter);
|
|
48
48
|
}, [debouncedTextFilter, textFilter]);
|
|
49
49
|
return (react_1.default.createElement("div", null,
|
|
50
|
-
react_1.default.createElement(material_1.TextField, { label: "text filter", value: textFilterValue, onChange: evt =>
|
|
50
|
+
react_1.default.createElement(material_1.TextField, { label: "text filter", value: textFilterValue, onChange: evt => {
|
|
51
|
+
setTextFilterValue(evt.target.value);
|
|
52
|
+
}, variant: "outlined", InputProps: {
|
|
51
53
|
startAdornment: (react_1.default.createElement(material_1.InputAdornment, { position: "start" },
|
|
52
54
|
react_1.default.createElement(FilterList_1.default, null))),
|
|
53
55
|
endAdornment: (react_1.default.createElement(material_1.InputAdornment, { className: classes.textFilterControlEndAdornment, position: "end" },
|
|
54
|
-
react_1.default.createElement(material_1.IconButton, { "aria-label": "clear filter", onClick: () =>
|
|
56
|
+
react_1.default.createElement(material_1.IconButton, { "aria-label": "clear filter", onClick: () => {
|
|
57
|
+
setTextFilterValue('');
|
|
58
|
+
} },
|
|
55
59
|
react_1.default.createElement(Clear_1.default, null)))),
|
|
56
60
|
} })));
|
|
57
61
|
});
|
|
58
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
59
62
|
const GlobalFilterControls = (0, mobx_react_1.observer)(({ model }) => {
|
|
60
63
|
const textFilter = model.filterControls.rowFullText;
|
|
61
64
|
return react_1.default.createElement(TextFilter, { textFilter: textFilter });
|
|
@@ -57,20 +57,30 @@ const ImportWizard = (0, mobx_react_1.observer)(({ model }) => {
|
|
|
57
57
|
react_1.default.createElement(material_1.FormControl, { component: "fieldset" },
|
|
58
58
|
react_1.default.createElement(material_1.FormLabel, { component: "legend" }, "Tabular file"),
|
|
59
59
|
react_1.default.createElement(material_1.FormGroup, null,
|
|
60
|
-
react_1.default.createElement(ui_1.FileSelector, { location: fileSource, setLocation: arg =>
|
|
60
|
+
react_1.default.createElement(ui_1.FileSelector, { location: fileSource, setLocation: arg => {
|
|
61
|
+
model.setFileSource(arg);
|
|
62
|
+
}, rootModel: rootModel })))),
|
|
61
63
|
react_1.default.createElement("div", null,
|
|
62
64
|
react_1.default.createElement(material_1.FormControl, { component: "fieldset" },
|
|
63
65
|
react_1.default.createElement(material_1.FormLabel, { component: "legend" }, "File Type"),
|
|
64
|
-
react_1.default.createElement(material_1.RadioGroup, { row: true, "aria-label": "file type", name: "type", value: fileType }, fileTypes.map(fileTypeName => (react_1.default.createElement(material_1.FormControlLabel, { key: fileTypeName, checked: fileType === fileTypeName, value: fileTypeName, onClick: () =>
|
|
66
|
+
react_1.default.createElement(material_1.RadioGroup, { row: true, "aria-label": "file type", name: "type", value: fileType }, fileTypes.map(fileTypeName => (react_1.default.createElement(material_1.FormControlLabel, { key: fileTypeName, checked: fileType === fileTypeName, value: fileTypeName, onClick: () => {
|
|
67
|
+
model.setFileType(fileTypeName);
|
|
68
|
+
}, control: react_1.default.createElement(material_1.Radio, null), label: fileTypeName })))))),
|
|
65
69
|
showRowControls ? (react_1.default.createElement("div", null,
|
|
66
70
|
react_1.default.createElement(material_1.FormControl, { component: "fieldset" },
|
|
67
71
|
react_1.default.createElement(material_1.FormLabel, { component: "legend" }, "Column Names"),
|
|
68
|
-
react_1.default.createElement(material_1.FormControlLabel, { disabled: !showRowControls, label: "has column names on line", labelPlacement: "end", control: react_1.default.createElement(material_1.Checkbox, { checked: hasColumnNameLine, onClick: () =>
|
|
69
|
-
|
|
72
|
+
react_1.default.createElement(material_1.FormControlLabel, { disabled: !showRowControls, label: "has column names on line", labelPlacement: "end", control: react_1.default.createElement(material_1.Checkbox, { checked: hasColumnNameLine, onClick: () => {
|
|
73
|
+
model.toggleHasColumnNameLine();
|
|
74
|
+
} }) }),
|
|
75
|
+
react_1.default.createElement(NumberEditor_1.default, { model: model, disabled: !hasColumnNameLine, modelPropName: "columnNameLineNumber", modelSetterName: "setColumnNameLineNumber" })))) : null,
|
|
70
76
|
react_1.default.createElement("div", null,
|
|
71
|
-
react_1.default.createElement(ui_1.AssemblySelector, { session: session, selected: selected, onChange: val =>
|
|
77
|
+
react_1.default.createElement(ui_1.AssemblySelector, { session: session, selected: selected, onChange: val => {
|
|
78
|
+
setSelected(val);
|
|
79
|
+
} })),
|
|
72
80
|
react_1.default.createElement("div", null,
|
|
73
|
-
canCancel ? (react_1.default.createElement(material_1.Button, { variant: "contained", color: "secondary", onClick: () =>
|
|
81
|
+
canCancel ? (react_1.default.createElement(material_1.Button, { variant: "contained", color: "secondary", onClick: () => {
|
|
82
|
+
model.cancelButton();
|
|
83
|
+
}, disabled: !canCancel }, "Cancel")) : null,
|
|
74
84
|
' ',
|
|
75
85
|
react_1.default.createElement(material_1.Button, { disabled: !isReadyToOpen || !!err, variant: "contained", "data-testid": "open_spreadsheet", color: "primary", onClick: () => {
|
|
76
86
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
@@ -49,6 +49,8 @@ const NumberEditor = (0, mobx_react_1.observer)(function ({ model, disabled, mod
|
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
}, [model, modelSetterName, val]);
|
|
52
|
-
return (react_1.default.createElement(material_1.TextField, { value: val, disabled: disabled, type: "number", onChange: evt =>
|
|
52
|
+
return (react_1.default.createElement(material_1.TextField, { value: val, disabled: disabled, type: "number", onChange: evt => {
|
|
53
|
+
setVal(evt.target.value);
|
|
54
|
+
}, className: classes.textField }));
|
|
53
55
|
});
|
|
54
56
|
exports.default = NumberEditor;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
type SpreadsheetModel = Instance<typeof SpreadsheetStateModel>;
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { SpreadsheetModel } from '../models/Spreadsheet';
|
|
4
3
|
declare const RowCountMessage: ({ spreadsheet, }: {
|
|
5
4
|
spreadsheet: SpreadsheetModel;
|
|
6
|
-
}) =>
|
|
5
|
+
}) => React.JSX.Element | null;
|
|
7
6
|
export default RowCountMessage;
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const react_1 = __importDefault(require("react"));
|
|
3
7
|
const mobx_react_1 = require("mobx-react");
|
|
4
8
|
const RowCountMessage = (0, mobx_react_1.observer)(function ({ spreadsheet, }) {
|
|
9
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
5
10
|
if (spreadsheet.rowSet.isLoaded) {
|
|
6
11
|
const { passingFiltersCount, count, selectedCount, selectedAndPassingFiltersCount, } = spreadsheet.rowSet;
|
|
7
12
|
let rowMessage;
|
|
@@ -21,7 +26,7 @@ const RowCountMessage = (0, mobx_react_1.observer)(function ({ spreadsheet, }) {
|
|
|
21
26
|
rowMessage += `, ${selectedCount} selected`;
|
|
22
27
|
}
|
|
23
28
|
}
|
|
24
|
-
return rowMessage;
|
|
29
|
+
return react_1.default.createElement(react_1.default.Fragment, null, rowMessage);
|
|
25
30
|
}
|
|
26
31
|
return null;
|
|
27
32
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Instance } from 'mobx-state-tree';
|
|
3
|
-
import SpreadsheetModel from '../models/Spreadsheet';
|
|
4
|
-
import ViewModel from '../models/SpreadsheetView';
|
|
3
|
+
import type SpreadsheetModel from '../models/Spreadsheet';
|
|
4
|
+
import type ViewModel from '../models/SpreadsheetView';
|
|
5
5
|
declare const RowMenu: ({ viewModel, spreadsheetModel, }: {
|
|
6
6
|
viewModel: Instance<typeof ViewModel>;
|
|
7
7
|
spreadsheetModel: Instance<typeof SpreadsheetModel>;
|
|
@@ -18,6 +18,7 @@ const RowMenu = (0, mobx_react_1.observer)(function ({ viewModel, spreadsheetMod
|
|
|
18
18
|
return null;
|
|
19
19
|
}
|
|
20
20
|
const row = spreadsheetModel.rowSet.rows[+rowNumber - 1];
|
|
21
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
21
22
|
function handleMenuItemClick(_event, callback) {
|
|
22
23
|
callback(viewModel, spreadsheetModel, rowNumber, row);
|
|
23
24
|
rowMenuClose();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Instance } from 'mobx-state-tree';
|
|
3
|
-
import SpreadsheetStateModel from '../models/Spreadsheet';
|
|
3
|
+
import type SpreadsheetStateModel from '../models/Spreadsheet';
|
|
4
4
|
type SpreadsheetModel = Instance<typeof SpreadsheetStateModel>;
|
|
5
5
|
declare const Spreadsheet: ({ model, height, page, rowsPerPage, }: {
|
|
6
6
|
model: SpreadsheetModel;
|
|
@@ -17,8 +17,9 @@ const useStyles = (0, mui_1.makeStyles)()(theme => ({
|
|
|
17
17
|
},
|
|
18
18
|
}));
|
|
19
19
|
const Spreadsheet = (0, mobx_react_1.observer)(function ({ model, height, page, rowsPerPage, }) {
|
|
20
|
-
var _a;
|
|
21
20
|
const { classes } = useStyles();
|
|
22
|
-
return (react_1.default.createElement("div", { className: classes.root, style: { height } },
|
|
21
|
+
return (react_1.default.createElement("div", { className: classes.root, style: { height } },
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
23
|
+
model.rowSet.isLoaded && model.initialized ? (react_1.default.createElement(DataTable_1.default, { model: model, page: page, rowsPerPage: rowsPerPage })) : (react_1.default.createElement(ui_1.LoadingEllipses, { variant: "h6" }))));
|
|
23
24
|
});
|
|
24
25
|
exports.default = Spreadsheet;
|
|
@@ -28,14 +28,17 @@ const useStyles = (0, mui_1.makeStyles)()(theme => ({
|
|
|
28
28
|
}));
|
|
29
29
|
const StatusBar = (0, mobx_react_1.observer)(function StatusBar({ page, rowsPerPage, setPage, setRowsPerPage, spreadsheet, mode, }) {
|
|
30
30
|
const { classes } = useStyles();
|
|
31
|
-
return (react_1.default.createElement("div", { className: classes.statusBar, style: { display: mode === 'display' ? undefined : 'none' } },
|
|
32
|
-
react_1.default.createElement(
|
|
33
|
-
react_1.default.createElement(
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
31
|
+
return (react_1.default.createElement("div", { className: classes.statusBar, style: { display: mode === 'display' ? undefined : 'none' } },
|
|
32
|
+
react_1.default.createElement(material_1.FormGroup, { row: true },
|
|
33
|
+
react_1.default.createElement("div", { className: classes.verticallyCenter },
|
|
34
|
+
react_1.default.createElement(RowCountMessage_1.default, { spreadsheet: spreadsheet })),
|
|
35
|
+
react_1.default.createElement("div", { className: classes.spacer }),
|
|
36
|
+
react_1.default.createElement(material_1.TablePagination, { rowsPerPageOptions: [10, 25, 100, 1000], count: spreadsheet.rowSet.count, component: "div", rowsPerPage: rowsPerPage, page: page, onPageChange: (_, newPage) => {
|
|
37
|
+
setPage(newPage);
|
|
38
|
+
}, onRowsPerPageChange: event => {
|
|
39
|
+
setRowsPerPage(+event.target.value);
|
|
40
|
+
setPage(0);
|
|
41
|
+
} }),
|
|
42
|
+
react_1.default.createElement("div", { className: classes.spacer }))));
|
|
40
43
|
});
|
|
41
44
|
exports.default = StatusBar;
|
|
@@ -35,7 +35,7 @@ function removeBedHeaders(buffer) {
|
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
if (i) {
|
|
38
|
-
return buffer.
|
|
38
|
+
return buffer.subarray(i);
|
|
39
39
|
}
|
|
40
40
|
return buffer;
|
|
41
41
|
}
|
|
@@ -110,12 +110,11 @@ async function parseBedPEBuffer(buffer, options) {
|
|
|
110
110
|
data.hasColumnNames = true;
|
|
111
111
|
// decorate each row with a feature object in its extendedData
|
|
112
112
|
data.rowSet.rows.forEach((row, rowNumber) => {
|
|
113
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
114
113
|
const featureData = {};
|
|
115
114
|
row.cells.forEach(({ text }, columnNumber) => {
|
|
116
115
|
const bedColumn = bedColumns[columnNumber];
|
|
117
116
|
const val = bedColumn && bedColumn.dataType.type === 'Number' && text
|
|
118
|
-
? parseFloat(text)
|
|
117
|
+
? Number.parseFloat(text)
|
|
119
118
|
: text;
|
|
120
119
|
if (bedColumn) {
|
|
121
120
|
// a predefined column
|
|
@@ -76,6 +76,7 @@ function dataToSpreadsheetSnapshot(rows, options = {}) {
|
|
|
76
76
|
};
|
|
77
77
|
// process the column names row if present
|
|
78
78
|
const columnNames = {};
|
|
79
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
79
80
|
if (hasColumnNameLine && columnNameLineNumber !== undefined) {
|
|
80
81
|
const [colNamesRow] = rowSet.rows.splice(columnNameLineNumber - 1, 1);
|
|
81
82
|
if (colNamesRow) {
|
|
@@ -33,7 +33,6 @@ async function parseSTARFusionBuffer(buffer, options) {
|
|
|
33
33
|
});
|
|
34
34
|
// decorate each row with a feature object in its extendedData
|
|
35
35
|
data.rowSet.rows.forEach((row, rowNumber) => {
|
|
36
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
37
36
|
const featureData = {};
|
|
38
37
|
row.cells.forEach(({ text }, columnNumber) => {
|
|
39
38
|
const column = data.columns[columnNumber];
|
|
@@ -55,7 +54,7 @@ async function parseSTARFusionBuffer(buffer, options) {
|
|
|
55
54
|
}
|
|
56
55
|
else if (text && numericColumns[column.name]) {
|
|
57
56
|
// some other column, numeric
|
|
58
|
-
featureData[column.name] = parseFloat(text);
|
|
57
|
+
featureData[column.name] = Number.parseFloat(text);
|
|
59
58
|
}
|
|
60
59
|
else {
|
|
61
60
|
// some other column, text
|
|
@@ -19,7 +19,6 @@ const vcfCoreColumns = [
|
|
|
19
19
|
{ name: 'INFO', type: 'Text' }, // 7
|
|
20
20
|
{ name: 'FORMAT', type: 'Text' }, // 8
|
|
21
21
|
];
|
|
22
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
23
22
|
function vcfRecordToRow(vcfParser, line, lineNumber) {
|
|
24
23
|
const vcfVariant = vcfParser.parseLine(line);
|
|
25
24
|
const vcfFeature = new plugin_variants_1.VcfFeature({
|
|
@@ -72,7 +71,10 @@ function parseVcfBuffer(buffer, options = {}) {
|
|
|
72
71
|
for (let i = 0; i < vcfParser.samples.length; i += 1) {
|
|
73
72
|
const oi = vcfCoreColumns.length + i;
|
|
74
73
|
columnDisplayOrder.push(oi);
|
|
75
|
-
columns[oi] = {
|
|
74
|
+
columns[oi] = {
|
|
75
|
+
name: vcfParser.samples[i],
|
|
76
|
+
dataType: { type: 'Text' },
|
|
77
|
+
};
|
|
76
78
|
}
|
|
77
79
|
columnDisplayOrder.push(columnDisplayOrder.length);
|
|
78
80
|
columns.unshift({
|
|
@@ -13,7 +13,7 @@ const LocEnd = (0, MakeSpreadsheetColumnType_1.default)('LocEnd', {
|
|
|
13
13
|
categoryName: 'Location',
|
|
14
14
|
displayName: 'End',
|
|
15
15
|
compare(cellA, cellB) {
|
|
16
|
-
return parseFloat(cellA.text) - parseFloat(cellB.text);
|
|
16
|
+
return Number.parseFloat(cellA.text) - Number.parseFloat(cellB.text);
|
|
17
17
|
},
|
|
18
18
|
FilterModelType,
|
|
19
19
|
});
|
|
@@ -13,7 +13,7 @@ const LocStart = (0, MakeSpreadsheetColumnType_1.default)('LocStart', {
|
|
|
13
13
|
categoryName: 'Location',
|
|
14
14
|
displayName: 'Start',
|
|
15
15
|
compare(cellA, cellB) {
|
|
16
|
-
return parseFloat(cellA.text) - parseFloat(cellB.text);
|
|
16
|
+
return Number.parseFloat(cellA.text) - Number.parseFloat(cellB.text);
|
|
17
17
|
},
|
|
18
18
|
FilterModelType,
|
|
19
19
|
});
|
|
@@ -80,7 +80,7 @@ const FilterModelType = mobx_state_tree_1.types
|
|
|
80
80
|
type: mobx_state_tree_1.types.literal('LocString'),
|
|
81
81
|
columnNumber: mobx_state_tree_1.types.integer,
|
|
82
82
|
locString: '',
|
|
83
|
-
operation: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.
|
|
83
|
+
operation: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.string, OPERATIONS[0]),
|
|
84
84
|
})
|
|
85
85
|
.views(self => ({
|
|
86
86
|
get locStringIsInvalid() {
|
|
@@ -96,7 +96,6 @@ const FilterModelType = mobx_state_tree_1.types
|
|
|
96
96
|
},
|
|
97
97
|
get parsedLocString() {
|
|
98
98
|
const session = (0, util_1.getSession)(self);
|
|
99
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
100
99
|
const model = (0, mobx_state_tree_1.getParent)(self, 3).spreadsheet;
|
|
101
100
|
const { assemblyName } = model;
|
|
102
101
|
try {
|
|
@@ -116,7 +115,6 @@ const FilterModelType = mobx_state_tree_1.types
|
|
|
116
115
|
return true;
|
|
117
116
|
};
|
|
118
117
|
}
|
|
119
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
120
118
|
return function stringPredicate(_sheet, row) {
|
|
121
119
|
const { cellsWithDerived: cells } = row;
|
|
122
120
|
const cell = cells[columnNumber];
|
|
@@ -145,14 +143,9 @@ const FilterModelType = mobx_state_tree_1.types
|
|
|
145
143
|
}))
|
|
146
144
|
.volatile(() => ({ ReactComponent: FilterReactComponent }));
|
|
147
145
|
// opens a new LGV at the location described in the locString in the cell text
|
|
148
|
-
async function locationLinkClick(
|
|
149
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
150
|
-
spreadsheet, _columnNumber,
|
|
151
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
152
|
-
cell) {
|
|
146
|
+
async function locationLinkClick(spreadsheet, _columnNumber, cell) {
|
|
153
147
|
const session = (0, util_1.getSession)(spreadsheet);
|
|
154
148
|
const { assemblyName } = spreadsheet;
|
|
155
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
156
149
|
const { id } = (0, mobx_state_tree_1.getParent)(spreadsheet);
|
|
157
150
|
const newViewId = `${id}_${assemblyName}`;
|
|
158
151
|
let view = session.views.find(v => v.id === newViewId);
|
|
@@ -174,12 +167,11 @@ const DataCellReactComponent = (0, mobx_react_1.observer)(function ({ cell, colu
|
|
|
174
167
|
console.error(e);
|
|
175
168
|
session.notifyError(`${e}`, e);
|
|
176
169
|
}
|
|
177
|
-
}, title: "open a new linear genome view here", href: "#
|
|
170
|
+
}, title: "open a new linear genome view here", href: "#" }, cell.text));
|
|
178
171
|
});
|
|
179
172
|
const LocStringColumnType = (0, MakeSpreadsheetColumnType_1.default)('LocString', {
|
|
180
173
|
categoryName: 'Location',
|
|
181
174
|
displayName: 'Full location',
|
|
182
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
183
175
|
compare(cellA, cellB) {
|
|
184
176
|
return (0, util_1.compareLocs)(cellA.extendedData, cellB.extendedData);
|
|
185
177
|
},
|
|
@@ -52,21 +52,19 @@ const useStyles = (0, mui_1.makeStyles)()({
|
|
|
52
52
|
},
|
|
53
53
|
});
|
|
54
54
|
// React component for the column filter control
|
|
55
|
-
const FilterReactComponent = (0, mobx_react_1.observer)(
|
|
56
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
57
|
-
({ filterModel }) => {
|
|
55
|
+
const FilterReactComponent = (0, mobx_react_1.observer)(({ filterModel }) => {
|
|
58
56
|
const { classes } = useStyles();
|
|
59
57
|
const operationChoices = OPERATIONS;
|
|
60
58
|
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
61
59
|
react_1.default.createElement(material_1.Select, { value: filterModel.operation, onChange: e => filterModel.setOperation(String(e.target.value)) }, operationChoices.map(name => (react_1.default.createElement(material_1.MenuItem, { key: name, value: name }, name)))),
|
|
62
60
|
' ',
|
|
63
61
|
react_1.default.createElement(material_1.TextField, { label: "number", placeholder: "123", type: "number", error: filterModel.firstNumberIsInvalid, defaultValue: filterModel.firstNumber, onChange: evt => {
|
|
64
|
-
filterModel.setFirstNumber(parseFloat(evt.target.value));
|
|
62
|
+
filterModel.setFirstNumber(Number.parseFloat(evt.target.value));
|
|
65
63
|
}, className: classes.textFilterControl }),
|
|
66
64
|
filterModel.operation !== 'between' &&
|
|
67
65
|
filterModel.operation !== 'not between' ? null : (react_1.default.createElement(react_1.default.Fragment, null,
|
|
68
66
|
' and ',
|
|
69
|
-
react_1.default.createElement(material_1.TextField, { label: "number", placeholder: "456", type: "number", error: filterModel.secondNumberIsInvalid, defaultValue: filterModel.secondNumber, onChange: evt => filterModel.setSecondNumber(parseFloat(evt.target.value)), className: classes.textFilterControl })))));
|
|
67
|
+
react_1.default.createElement(material_1.TextField, { label: "number", placeholder: "456", type: "number", error: filterModel.secondNumberIsInvalid, defaultValue: filterModel.secondNumber, onChange: evt => filterModel.setSecondNumber(Number.parseFloat(evt.target.value)), className: classes.textFilterControl })))));
|
|
70
68
|
});
|
|
71
69
|
// MST model for the column filter control
|
|
72
70
|
const FilterModelType = mobx_state_tree_1.types
|
|
@@ -86,14 +84,13 @@ const FilterModelType = mobx_state_tree_1.types
|
|
|
86
84
|
};
|
|
87
85
|
}
|
|
88
86
|
const { firstNumber, secondNumber, operation, columnNumber } = self; // avoid closing over self
|
|
89
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
90
87
|
return function stringPredicate(_sheet, row) {
|
|
91
88
|
const { cellsWithDerived } = row;
|
|
92
89
|
const cell = cellsWithDerived[columnNumber];
|
|
93
90
|
if (!(cell === null || cell === void 0 ? void 0 : cell.text)) {
|
|
94
91
|
return false;
|
|
95
92
|
}
|
|
96
|
-
const parsedCellText = parseFloat(cell.text);
|
|
93
|
+
const parsedCellText = Number.parseFloat(cell.text);
|
|
97
94
|
if (typeof parsedCellText !== 'number') {
|
|
98
95
|
return false;
|
|
99
96
|
}
|
|
@@ -122,7 +119,7 @@ const FilterModelType = mobx_state_tree_1.types
|
|
|
122
119
|
exports.FilterModelType = FilterModelType;
|
|
123
120
|
const NumberColumn = (0, MakeSpreadsheetColumnType_1.default)('Number', {
|
|
124
121
|
compare(cellA, cellB) {
|
|
125
|
-
return parseFloat(cellA.text) - parseFloat(cellB.text);
|
|
122
|
+
return Number.parseFloat(cellA.text) - Number.parseFloat(cellB.text);
|
|
126
123
|
},
|
|
127
124
|
FilterModelType,
|
|
128
125
|
});
|
|
@@ -62,9 +62,7 @@ const useStyles = (0, mui_1.makeStyles)()({
|
|
|
62
62
|
},
|
|
63
63
|
});
|
|
64
64
|
// React component for the column filter control
|
|
65
|
-
const FilterReactComponent = (0, mobx_react_1.observer)(
|
|
66
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
67
|
-
({ filterModel }) => {
|
|
65
|
+
const FilterReactComponent = (0, mobx_react_1.observer)(({ filterModel }) => {
|
|
68
66
|
const { classes } = useStyles();
|
|
69
67
|
const operationChoices = (0, mst_reflection_1.getEnumerationValues)((0, mst_reflection_1.getSubType)((0, mst_reflection_1.getPropertyType)((0, mobx_state_tree_1.getPropertyMembers)(filterModel), 'operation')));
|
|
70
68
|
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
@@ -96,7 +94,6 @@ const ColumnTextFilter = mobx_state_tree_1.types
|
|
|
96
94
|
};
|
|
97
95
|
}
|
|
98
96
|
const s = stringToFind.toLowerCase(); // case insensitive match
|
|
99
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
100
97
|
return function stringPredicate(_sheet, row) {
|
|
101
98
|
const { cellsWithDerived } = row;
|
|
102
99
|
const cell = cellsWithDerived[columnNumber];
|