@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
|
@@ -19,11 +19,10 @@ const RowFullTextFilter = mobx_state_tree_1.types
|
|
|
19
19
|
}
|
|
20
20
|
s = s.toLowerCase();
|
|
21
21
|
return function stringPredicate(_sheet, row) {
|
|
22
|
-
var _a;
|
|
23
22
|
const { cellsWithDerived } = row;
|
|
24
23
|
for (const cell of cellsWithDerived) {
|
|
25
24
|
// note: case insensitive
|
|
26
|
-
if (
|
|
25
|
+
if (cell.text.toLowerCase().includes(s)) {
|
|
27
26
|
return true;
|
|
28
27
|
}
|
|
29
28
|
}
|
|
@@ -69,9 +68,7 @@ const model = mobx_state_tree_1.types
|
|
|
69
68
|
}))
|
|
70
69
|
.actions(self => ({
|
|
71
70
|
addBlankColumnFilter(columnNumber) {
|
|
72
|
-
const { dataType } =
|
|
73
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
74
|
-
(0, mobx_state_tree_1.getParent)(self).spreadsheet.columns[columnNumber];
|
|
71
|
+
const { dataType } = (0, mobx_state_tree_1.getParent)(self).spreadsheet.columns[columnNumber];
|
|
75
72
|
self.columnFilters.push({
|
|
76
73
|
type: dataType.type,
|
|
77
74
|
columnNumber,
|
|
@@ -65,7 +65,6 @@ const ImportWizard = mobx_state_tree_1.types
|
|
|
65
65
|
})
|
|
66
66
|
.volatile(() => ({
|
|
67
67
|
fileTypes,
|
|
68
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
69
68
|
fileSource: undefined,
|
|
70
69
|
error: undefined,
|
|
71
70
|
loading: false,
|
|
@@ -79,7 +78,6 @@ const ImportWizard = mobx_state_tree_1.types
|
|
|
79
78
|
self.fileSource.uri));
|
|
80
79
|
},
|
|
81
80
|
get canCancel() {
|
|
82
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
83
81
|
return (0, mobx_state_tree_1.getParent)(self).readyToDisplay;
|
|
84
82
|
},
|
|
85
83
|
get fileName() {
|
|
@@ -142,7 +140,6 @@ const ImportWizard = mobx_state_tree_1.types
|
|
|
142
140
|
},
|
|
143
141
|
cancelButton() {
|
|
144
142
|
self.error = undefined;
|
|
145
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
146
143
|
(0, mobx_state_tree_1.getParent)(self).setDisplayMode();
|
|
147
144
|
},
|
|
148
145
|
// fetch and parse the file, make a new Spreadsheet model for it,
|
|
@@ -158,9 +155,6 @@ const ImportWizard = mobx_state_tree_1.types
|
|
|
158
155
|
self.loading = true;
|
|
159
156
|
const type = self.fileType;
|
|
160
157
|
const typeParser = await fileTypeParsers[type]();
|
|
161
|
-
if (!typeParser) {
|
|
162
|
-
throw new Error(`cannot open files of type '${self.fileType}'`);
|
|
163
|
-
}
|
|
164
158
|
const { unzip } = await Promise.resolve().then(() => __importStar(require('@gmod/bgzf-filehandle')));
|
|
165
159
|
const { pluginManager } = (0, util_1.getEnv)(self);
|
|
166
160
|
const filehandle = (0, io_1.openLocation)(self.fileSource, pluginManager);
|
|
@@ -181,7 +175,6 @@ const ImportWizard = mobx_state_tree_1.types
|
|
|
181
175
|
.then(buffer => typeParser(buffer, self))
|
|
182
176
|
.then(spreadsheet => {
|
|
183
177
|
this.setLoaded();
|
|
184
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
185
178
|
(0, mobx_state_tree_1.getParent)(self).displaySpreadsheet(spreadsheet);
|
|
186
179
|
});
|
|
187
180
|
}
|
|
@@ -28,10 +28,8 @@ const RowModel = mobx_state_tree_1.types
|
|
|
28
28
|
}))
|
|
29
29
|
.views(self => ({
|
|
30
30
|
get cellsWithDerived() {
|
|
31
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
32
31
|
const { columns } = (0, mobx_state_tree_1.getParent)(self, 3);
|
|
33
32
|
let i = 0;
|
|
34
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
35
33
|
return columns.map((column) => {
|
|
36
34
|
if (column.isDerived) {
|
|
37
35
|
return column.expr.evalSync({
|
|
@@ -91,7 +91,6 @@ const Spreadsheet = mobx_state_tree_1.types
|
|
|
91
91
|
*/
|
|
92
92
|
get hideRowSelection() {
|
|
93
93
|
// just delegates to parent
|
|
94
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
95
94
|
return (0, mobx_state_tree_1.getParent)(self).hideRowSelection;
|
|
96
95
|
},
|
|
97
96
|
/**
|
|
@@ -153,6 +152,7 @@ const Spreadsheet = mobx_state_tree_1.types
|
|
|
153
152
|
* #action
|
|
154
153
|
*/
|
|
155
154
|
setSortColumns(newSort) {
|
|
155
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
156
156
|
if (newSort) {
|
|
157
157
|
// @ts-expect-error
|
|
158
158
|
self.sortColumns = newSort;
|
|
@@ -168,7 +168,7 @@ const Spreadsheet = mobx_state_tree_1.types
|
|
|
168
168
|
* #action
|
|
169
169
|
*/
|
|
170
170
|
unselectAll() {
|
|
171
|
-
|
|
171
|
+
self.rowSet.unselectAll();
|
|
172
172
|
},
|
|
173
173
|
}));
|
|
174
174
|
exports.default = Spreadsheet;
|
|
@@ -95,7 +95,8 @@ const model = mobx_state_tree_1.types
|
|
|
95
95
|
* #getter
|
|
96
96
|
*/
|
|
97
97
|
get outputRows() {
|
|
98
|
-
|
|
98
|
+
var _a;
|
|
99
|
+
if ((_a = self.spreadsheet) === null || _a === void 0 ? void 0 : _a.rowSet.isLoaded) {
|
|
99
100
|
const selected = self.spreadsheet.rowSet.selectedFilteredRows;
|
|
100
101
|
if (selected.length) {
|
|
101
102
|
return selected;
|
|
@@ -112,7 +113,7 @@ const model = mobx_state_tree_1.types
|
|
|
112
113
|
const name = (_a = self.spreadsheet) === null || _a === void 0 ? void 0 : _a.assemblyName;
|
|
113
114
|
if (name) {
|
|
114
115
|
const assemblies = (0, util_1.getSession)(self).assemblies;
|
|
115
|
-
return assemblies
|
|
116
|
+
return assemblies.find(asm => (0, configuration_1.readConfObject)(asm, 'name') === name);
|
|
116
117
|
}
|
|
117
118
|
return undefined;
|
|
118
119
|
},
|
|
@@ -177,13 +178,6 @@ const model = mobx_state_tree_1.types
|
|
|
177
178
|
self.mode = 'display';
|
|
178
179
|
}
|
|
179
180
|
},
|
|
180
|
-
/**
|
|
181
|
-
* #action
|
|
182
|
-
*/
|
|
183
|
-
closeView() {
|
|
184
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
185
|
-
(0, mobx_state_tree_1.getParent)(self, 2).removeView(self);
|
|
186
|
-
},
|
|
187
181
|
}))
|
|
188
182
|
.views(self => ({
|
|
189
183
|
/**
|
|
@@ -193,7 +187,9 @@ const model = mobx_state_tree_1.types
|
|
|
193
187
|
return [
|
|
194
188
|
{
|
|
195
189
|
label: 'Return to import form',
|
|
196
|
-
onClick: () =>
|
|
190
|
+
onClick: () => {
|
|
191
|
+
self.setImportMode();
|
|
192
|
+
},
|
|
197
193
|
icon: FolderOpen_1.default,
|
|
198
194
|
},
|
|
199
195
|
];
|
|
@@ -24,7 +24,6 @@ const StaticRowModel = mobx_state_tree_1.types
|
|
|
24
24
|
return this.selectedFilteredRows.length;
|
|
25
25
|
},
|
|
26
26
|
get sortedRows() {
|
|
27
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
28
27
|
const parent = (0, mobx_state_tree_1.getParent)(self);
|
|
29
28
|
return [...self.rows].sort(parent.rowSortingComparisonFunction);
|
|
30
29
|
},
|
|
@@ -32,18 +31,14 @@ const StaticRowModel = mobx_state_tree_1.types
|
|
|
32
31
|
return self.rows.filter(r => r.isSelected);
|
|
33
32
|
},
|
|
34
33
|
get selectedFilteredRows() {
|
|
35
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
36
34
|
const sheet = (0, mobx_state_tree_1.getParent)(self);
|
|
37
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
38
35
|
const view = (0, mobx_state_tree_1.getParent)(sheet);
|
|
39
36
|
const { filterControls } = view;
|
|
40
37
|
return this.selectedRows.filter(row => filterControls.rowPassesFilters(sheet, row));
|
|
41
38
|
},
|
|
42
39
|
// the set of all rows that pass the filters, sorted
|
|
43
40
|
get sortedFilteredRows() {
|
|
44
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
45
41
|
const sheet = (0, mobx_state_tree_1.getParent)(self);
|
|
46
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
47
42
|
const view = (0, mobx_state_tree_1.getParent)(sheet);
|
|
48
43
|
const { filterControls } = view;
|
|
49
44
|
return self.rows
|
|
@@ -53,7 +48,9 @@ const StaticRowModel = mobx_state_tree_1.types
|
|
|
53
48
|
}))
|
|
54
49
|
.actions(self => ({
|
|
55
50
|
unselectAll() {
|
|
56
|
-
self.rows.forEach(row =>
|
|
51
|
+
self.rows.forEach(row => {
|
|
52
|
+
row.unSelect();
|
|
53
|
+
});
|
|
57
54
|
},
|
|
58
55
|
}));
|
|
59
56
|
exports.default = StaticRowModel;
|
|
@@ -4,13 +4,10 @@ export default function LaunchSpreadsheetViewF(pluginManager) {
|
|
|
4
4
|
async ({ session, assembly, uri, fileType, }) => {
|
|
5
5
|
var _a, _b;
|
|
6
6
|
const view = session.addView('SpreadsheetView');
|
|
7
|
-
if (!view) {
|
|
8
|
-
throw new Error('Failed to initialize view');
|
|
9
|
-
}
|
|
10
7
|
const exts = uri.split('.');
|
|
11
|
-
let ext = (_a = exts
|
|
8
|
+
let ext = (_a = exts.pop()) === null || _a === void 0 ? void 0 : _a.toUpperCase();
|
|
12
9
|
if (ext === 'GZ') {
|
|
13
|
-
ext = (_b = exts
|
|
10
|
+
ext = (_b = exts.pop()) === null || _b === void 0 ? void 0 : _b.toUpperCase();
|
|
14
11
|
}
|
|
15
12
|
view.importWizard.setFileType(fileType || ext || '');
|
|
16
13
|
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;
|
|
@@ -28,7 +28,6 @@ const useStyles = makeStyles()(theme => ({
|
|
|
28
28
|
padding: theme.spacing(1.5),
|
|
29
29
|
},
|
|
30
30
|
}));
|
|
31
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
32
31
|
function FilterOperations({ filterModel }) {
|
|
33
32
|
if (filterModel) {
|
|
34
33
|
return React.createElement(filterModel.ReactComponent, { filterModel: filterModel });
|
|
@@ -45,9 +44,7 @@ const ColumnFilterControls = observer(function ({ viewModel, filterModel, column
|
|
|
45
44
|
React.createElement(Grid, { item: true, className: classes.filterIconBg },
|
|
46
45
|
React.createElement(FilterIcon, { className: classes.filterIcon })),
|
|
47
46
|
React.createElement(Grid, { item: true },
|
|
48
|
-
React.createElement(IconButton, { onClick: () =>
|
|
49
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
50
|
-
getParent(filterModel, 2).removeColumnFilter(filterModel), title: "remove filter" },
|
|
47
|
+
React.createElement(IconButton, { onClick: () => getParent(filterModel, 2).removeColumnFilter(filterModel), title: "remove filter" },
|
|
51
48
|
React.createElement(CloseIcon, null)),
|
|
52
49
|
React.createElement(Typography, { className: classes.columnName, component: "span" }, columnDefinition.name),
|
|
53
50
|
' ',
|
|
@@ -8,7 +8,9 @@ import FilterListIcon from '@mui/icons-material/FilterList';
|
|
|
8
8
|
import PermDataSettingIcon from '@mui/icons-material/PermDataSetting';
|
|
9
9
|
import SortIcon from '@mui/icons-material/Sort';
|
|
10
10
|
const ColumnMenu = observer(function ({ viewModel, spreadsheetModel, currentColumnMenu, setColumnMenu, }) {
|
|
11
|
-
const columnMenuClose = () =>
|
|
11
|
+
const columnMenuClose = () => {
|
|
12
|
+
setColumnMenu(undefined);
|
|
13
|
+
};
|
|
12
14
|
const columnNumber = (currentColumnMenu === null || currentColumnMenu === void 0 ? void 0 : currentColumnMenu.colNumber) || 0;
|
|
13
15
|
const sortMenuClick = (descending) => {
|
|
14
16
|
spreadsheetModel.setSortColumns([
|
|
@@ -52,36 +54,46 @@ const ColumnMenu = observer(function ({ viewModel, spreadsheetModel, currentColu
|
|
|
52
54
|
icon: SortIcon,
|
|
53
55
|
type: 'radio',
|
|
54
56
|
checked: isSortingAscending,
|
|
55
|
-
onClick: () =>
|
|
57
|
+
onClick: () => {
|
|
58
|
+
sortMenuClick(false);
|
|
59
|
+
},
|
|
56
60
|
},
|
|
57
61
|
{
|
|
58
62
|
label: 'Sort descending',
|
|
59
63
|
icon: SortIcon,
|
|
60
64
|
type: 'radio',
|
|
61
65
|
checked: isSortingDescending,
|
|
62
|
-
onClick: () =>
|
|
66
|
+
onClick: () => {
|
|
67
|
+
sortMenuClick(true);
|
|
68
|
+
},
|
|
63
69
|
},
|
|
64
70
|
{
|
|
65
71
|
label: 'No sort',
|
|
66
72
|
icon: SortIcon,
|
|
67
73
|
type: 'radio',
|
|
68
74
|
checked: !isSortingDescending && !isSortingAscending,
|
|
69
|
-
onClick: () =>
|
|
75
|
+
onClick: () => {
|
|
76
|
+
spreadsheetModel.setSortColumns([]);
|
|
77
|
+
},
|
|
70
78
|
},
|
|
71
79
|
// data type menu
|
|
72
80
|
{
|
|
73
81
|
label: `Type: ${dataTypeDisplayName}`,
|
|
74
82
|
icon: PermDataSettingIcon,
|
|
75
83
|
subMenu: iterMap(dataTypeTopLevelMenu.entries(), ([displayName, record]) => {
|
|
84
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
76
85
|
if ('typeName' in record && record.typeName) {
|
|
77
86
|
const { typeName } = record;
|
|
78
87
|
return {
|
|
79
88
|
label: displayName || typeName,
|
|
80
89
|
icon: dataTypeName === typeName ? CheckIcon : undefined,
|
|
81
|
-
onClick: () =>
|
|
90
|
+
onClick: () => {
|
|
91
|
+
spreadsheetModel.setColumnType(columnNumber, typeName);
|
|
92
|
+
},
|
|
82
93
|
};
|
|
83
94
|
}
|
|
84
|
-
|
|
95
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
96
|
+
if ('subMenuItems' in record && record.subMenuItems) {
|
|
85
97
|
const { subMenuItems } = record;
|
|
86
98
|
return {
|
|
87
99
|
label: displayName,
|
|
@@ -91,13 +103,13 @@ const ColumnMenu = observer(function ({ viewModel, spreadsheetModel, currentColu
|
|
|
91
103
|
subMenu: subMenuItems.map(({ typeName, displayName }) => ({
|
|
92
104
|
label: displayName,
|
|
93
105
|
icon: typeName === dataTypeName ? CheckIcon : undefined,
|
|
94
|
-
onClick: () =>
|
|
106
|
+
onClick: () => {
|
|
107
|
+
spreadsheetModel.setColumnType(columnNumber, typeName);
|
|
108
|
+
},
|
|
95
109
|
})),
|
|
96
110
|
};
|
|
97
111
|
}
|
|
98
|
-
|
|
99
|
-
return null;
|
|
100
|
-
}
|
|
112
|
+
return null;
|
|
101
113
|
}).filter(Boolean),
|
|
102
114
|
},
|
|
103
115
|
];
|
|
@@ -107,7 +119,9 @@ const ColumnMenu = observer(function ({ viewModel, spreadsheetModel, currentColu
|
|
|
107
119
|
menuItems.push({
|
|
108
120
|
label: 'Create filter',
|
|
109
121
|
icon: FilterListIcon,
|
|
110
|
-
onClick: () =>
|
|
122
|
+
onClick: () => {
|
|
123
|
+
viewModel.filterControls.addBlankColumnFilter(columnNumber);
|
|
124
|
+
},
|
|
111
125
|
});
|
|
112
126
|
}
|
|
113
127
|
return (React.createElement(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, }: {
|
|
@@ -51,7 +51,7 @@ const DataRow = observer(function ({ rowModel, rowNumber, spreadsheetModel, }) {
|
|
|
51
51
|
const { hideRowSelection, columnDisplayOrder } = spreadsheetModel;
|
|
52
52
|
let rowClass = '';
|
|
53
53
|
if (rowModel.isSelected) {
|
|
54
|
-
rowClass +=
|
|
54
|
+
rowClass += classes.dataRowSelected;
|
|
55
55
|
}
|
|
56
56
|
function labelClick(evt) {
|
|
57
57
|
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;
|
|
@@ -46,28 +46,31 @@ const DataTableHeader = observer(function ({ model, }) {
|
|
|
46
46
|
React.createElement("th", { className: classes.topLeftCorner },
|
|
47
47
|
React.createElement(Tooltip, { title: "Unselect all", placement: "right" },
|
|
48
48
|
React.createElement("span", null,
|
|
49
|
-
React.createElement(IconButton, { onClick: () =>
|
|
49
|
+
React.createElement(IconButton, { onClick: () => {
|
|
50
|
+
model.unselectAll();
|
|
51
|
+
}, disabled: !rowSet.selectedCount },
|
|
50
52
|
React.createElement(CropFreeIcon, null))))),
|
|
51
|
-
columnDisplayOrder.map(colNumber => {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
53
|
+
columnDisplayOrder.map(colNumber => (React.createElement("th", { className: classes.columnHead, key: colNumber, onMouseOver: () => {
|
|
54
|
+
setHoveredColumn(colNumber);
|
|
55
|
+
}, onMouseOut: () => {
|
|
56
|
+
setHoveredColumn(undefined);
|
|
57
|
+
} },
|
|
58
|
+
React.createElement(SortIndicator, { model: model, columnNumber: colNumber }),
|
|
59
|
+
(hasColumnNames && columns[colNumber].name) ||
|
|
60
|
+
numToColName(colNumber),
|
|
61
|
+
React.createElement("div", { className: classes.columnButtonContainer, style: {
|
|
62
|
+
display: currentHoveredColumn === colNumber ||
|
|
63
|
+
(currentColumnMenu === null || currentColumnMenu === void 0 ? void 0 : currentColumnMenu.colNumber) === colNumber
|
|
64
|
+
? 'block'
|
|
65
|
+
: 'none',
|
|
66
|
+
} },
|
|
67
|
+
React.createElement(IconButton, { onClick: evt => {
|
|
68
|
+
setColumnMenu({
|
|
69
|
+
colNumber,
|
|
70
|
+
anchorEl: evt.currentTarget,
|
|
71
|
+
});
|
|
62
72
|
} },
|
|
63
|
-
React.createElement(
|
|
64
|
-
setColumnMenu({
|
|
65
|
-
colNumber,
|
|
66
|
-
anchorEl: evt.currentTarget,
|
|
67
|
-
});
|
|
68
|
-
} },
|
|
69
|
-
React.createElement(ArrowDropDown, null)))));
|
|
70
|
-
}))),
|
|
73
|
+
React.createElement(ArrowDropDown, null)))))))),
|
|
71
74
|
React.createElement(ColumnMenu, { viewModel: getParent(model), spreadsheetModel: model, currentColumnMenu: currentColumnMenu, setColumnMenu: setColumnMenu })));
|
|
72
75
|
});
|
|
73
76
|
export default DataTableHeader;
|
|
@@ -19,15 +19,18 @@ const TextFilter = observer(function ({ textFilter, }) {
|
|
|
19
19
|
textFilter.setString(debouncedTextFilter);
|
|
20
20
|
}, [debouncedTextFilter, textFilter]);
|
|
21
21
|
return (React.createElement("div", null,
|
|
22
|
-
React.createElement(TextField, { label: "text filter", value: textFilterValue, onChange: evt =>
|
|
22
|
+
React.createElement(TextField, { label: "text filter", value: textFilterValue, onChange: evt => {
|
|
23
|
+
setTextFilterValue(evt.target.value);
|
|
24
|
+
}, variant: "outlined", InputProps: {
|
|
23
25
|
startAdornment: (React.createElement(InputAdornment, { position: "start" },
|
|
24
26
|
React.createElement(FilterIcon, null))),
|
|
25
27
|
endAdornment: (React.createElement(InputAdornment, { className: classes.textFilterControlEndAdornment, position: "end" },
|
|
26
|
-
React.createElement(IconButton, { "aria-label": "clear filter", onClick: () =>
|
|
28
|
+
React.createElement(IconButton, { "aria-label": "clear filter", onClick: () => {
|
|
29
|
+
setTextFilterValue('');
|
|
30
|
+
} },
|
|
27
31
|
React.createElement(ClearIcon, null)))),
|
|
28
32
|
} })));
|
|
29
33
|
});
|
|
30
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
31
34
|
const GlobalFilterControls = observer(({ model }) => {
|
|
32
35
|
const textFilter = model.filterControls.rowFullText;
|
|
33
36
|
return React.createElement(TextFilter, { textFilter: textFilter });
|
|
@@ -29,20 +29,30 @@ const ImportWizard = observer(({ model }) => {
|
|
|
29
29
|
React.createElement(FormControl, { component: "fieldset" },
|
|
30
30
|
React.createElement(FormLabel, { component: "legend" }, "Tabular file"),
|
|
31
31
|
React.createElement(FormGroup, null,
|
|
32
|
-
React.createElement(FileSelector, { location: fileSource, setLocation: arg =>
|
|
32
|
+
React.createElement(FileSelector, { location: fileSource, setLocation: arg => {
|
|
33
|
+
model.setFileSource(arg);
|
|
34
|
+
}, rootModel: rootModel })))),
|
|
33
35
|
React.createElement("div", null,
|
|
34
36
|
React.createElement(FormControl, { component: "fieldset" },
|
|
35
37
|
React.createElement(FormLabel, { component: "legend" }, "File Type"),
|
|
36
|
-
React.createElement(RadioGroup, { row: true, "aria-label": "file type", name: "type", value: fileType }, fileTypes.map(fileTypeName => (React.createElement(FormControlLabel, { key: fileTypeName, checked: fileType === fileTypeName, value: fileTypeName, onClick: () =>
|
|
38
|
+
React.createElement(RadioGroup, { row: true, "aria-label": "file type", name: "type", value: fileType }, fileTypes.map(fileTypeName => (React.createElement(FormControlLabel, { key: fileTypeName, checked: fileType === fileTypeName, value: fileTypeName, onClick: () => {
|
|
39
|
+
model.setFileType(fileTypeName);
|
|
40
|
+
}, control: React.createElement(Radio, null), label: fileTypeName })))))),
|
|
37
41
|
showRowControls ? (React.createElement("div", null,
|
|
38
42
|
React.createElement(FormControl, { component: "fieldset" },
|
|
39
43
|
React.createElement(FormLabel, { component: "legend" }, "Column Names"),
|
|
40
|
-
React.createElement(FormControlLabel, { disabled: !showRowControls, label: "has column names on line", labelPlacement: "end", control: React.createElement(Checkbox, { checked: hasColumnNameLine, onClick: () =>
|
|
41
|
-
|
|
44
|
+
React.createElement(FormControlLabel, { disabled: !showRowControls, label: "has column names on line", labelPlacement: "end", control: React.createElement(Checkbox, { checked: hasColumnNameLine, onClick: () => {
|
|
45
|
+
model.toggleHasColumnNameLine();
|
|
46
|
+
} }) }),
|
|
47
|
+
React.createElement(NumberEditor, { model: model, disabled: !hasColumnNameLine, modelPropName: "columnNameLineNumber", modelSetterName: "setColumnNameLineNumber" })))) : null,
|
|
42
48
|
React.createElement("div", null,
|
|
43
|
-
React.createElement(AssemblySelector, { session: session, selected: selected, onChange: val =>
|
|
49
|
+
React.createElement(AssemblySelector, { session: session, selected: selected, onChange: val => {
|
|
50
|
+
setSelected(val);
|
|
51
|
+
} })),
|
|
44
52
|
React.createElement("div", null,
|
|
45
|
-
canCancel ? (React.createElement(Button, { variant: "contained", color: "secondary", onClick: () =>
|
|
53
|
+
canCancel ? (React.createElement(Button, { variant: "contained", color: "secondary", onClick: () => {
|
|
54
|
+
model.cancelButton();
|
|
55
|
+
}, disabled: !canCancel }, "Cancel")) : null,
|
|
46
56
|
' ',
|
|
47
57
|
React.createElement(Button, { disabled: !isReadyToOpen || !!err, variant: "contained", "data-testid": "open_spreadsheet", color: "primary", onClick: () => {
|
|
48
58
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
@@ -24,6 +24,8 @@ const NumberEditor = observer(function ({ model, disabled, modelPropName, modelS
|
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
}, [model, modelSetterName, val]);
|
|
27
|
-
return (React.createElement(TextField, { value: val, disabled: disabled, type: "number", onChange: evt =>
|
|
27
|
+
return (React.createElement(TextField, { value: val, disabled: disabled, type: "number", onChange: evt => {
|
|
28
|
+
setVal(evt.target.value);
|
|
29
|
+
}, className: classes.textField }));
|
|
28
30
|
});
|
|
29
31
|
export 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,5 +1,7 @@
|
|
|
1
|
+
import React from 'react';
|
|
1
2
|
import { observer } from 'mobx-react';
|
|
2
3
|
const RowCountMessage = observer(function ({ spreadsheet, }) {
|
|
4
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
3
5
|
if (spreadsheet.rowSet.isLoaded) {
|
|
4
6
|
const { passingFiltersCount, count, selectedCount, selectedAndPassingFiltersCount, } = spreadsheet.rowSet;
|
|
5
7
|
let rowMessage;
|
|
@@ -19,7 +21,7 @@ const RowCountMessage = observer(function ({ spreadsheet, }) {
|
|
|
19
21
|
rowMessage += `, ${selectedCount} selected`;
|
|
20
22
|
}
|
|
21
23
|
}
|
|
22
|
-
return rowMessage;
|
|
24
|
+
return React.createElement(React.Fragment, null, rowMessage);
|
|
23
25
|
}
|
|
24
26
|
return null;
|
|
25
27
|
});
|
|
@@ -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>;
|
|
@@ -13,6 +13,7 @@ const RowMenu = observer(function ({ viewModel, spreadsheetModel, }) {
|
|
|
13
13
|
return null;
|
|
14
14
|
}
|
|
15
15
|
const row = spreadsheetModel.rowSet.rows[+rowNumber - 1];
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
16
17
|
function handleMenuItemClick(_event, callback) {
|
|
17
18
|
callback(viewModel, spreadsheetModel, rowNumber, row);
|
|
18
19
|
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;
|
|
@@ -12,8 +12,9 @@ const useStyles = makeStyles()(theme => ({
|
|
|
12
12
|
},
|
|
13
13
|
}));
|
|
14
14
|
const Spreadsheet = observer(function ({ model, height, page, rowsPerPage, }) {
|
|
15
|
-
var _a;
|
|
16
15
|
const { classes } = useStyles();
|
|
17
|
-
return (React.createElement("div", { className: classes.root, style: { height } },
|
|
16
|
+
return (React.createElement("div", { className: classes.root, style: { height } },
|
|
17
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
18
|
+
model.rowSet.isLoaded && model.initialized ? (React.createElement(DataTable, { model: model, page: page, rowsPerPage: rowsPerPage })) : (React.createElement(LoadingEllipses, { variant: "h6" }))));
|
|
18
19
|
});
|
|
19
20
|
export default Spreadsheet;
|
|
@@ -23,14 +23,17 @@ const useStyles = makeStyles()(theme => ({
|
|
|
23
23
|
}));
|
|
24
24
|
const StatusBar = observer(function StatusBar({ page, rowsPerPage, setPage, setRowsPerPage, spreadsheet, mode, }) {
|
|
25
25
|
const { classes } = useStyles();
|
|
26
|
-
return (React.createElement("div", { className: classes.statusBar, style: { display: mode === 'display' ? undefined : 'none' } },
|
|
27
|
-
React.createElement(
|
|
28
|
-
React.createElement(
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
26
|
+
return (React.createElement("div", { className: classes.statusBar, style: { display: mode === 'display' ? undefined : 'none' } },
|
|
27
|
+
React.createElement(FormGroup, { row: true },
|
|
28
|
+
React.createElement("div", { className: classes.verticallyCenter },
|
|
29
|
+
React.createElement(RowCountMessage, { spreadsheet: spreadsheet })),
|
|
30
|
+
React.createElement("div", { className: classes.spacer }),
|
|
31
|
+
React.createElement(TablePagination, { rowsPerPageOptions: [10, 25, 100, 1000], count: spreadsheet.rowSet.count, component: "div", rowsPerPage: rowsPerPage, page: page, onPageChange: (_, newPage) => {
|
|
32
|
+
setPage(newPage);
|
|
33
|
+
}, onRowsPerPageChange: event => {
|
|
34
|
+
setRowsPerPage(+event.target.value);
|
|
35
|
+
setPage(0);
|
|
36
|
+
} }),
|
|
37
|
+
React.createElement("div", { className: classes.spacer }))));
|
|
35
38
|
});
|
|
36
39
|
export default StatusBar;
|
|
@@ -30,7 +30,7 @@ export function removeBedHeaders(buffer) {
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
if (i) {
|
|
33
|
-
return buffer.
|
|
33
|
+
return buffer.subarray(i);
|
|
34
34
|
}
|
|
35
35
|
return buffer;
|
|
36
36
|
}
|
|
@@ -105,12 +105,11 @@ export async function parseBedPEBuffer(buffer, options) {
|
|
|
105
105
|
data.hasColumnNames = true;
|
|
106
106
|
// decorate each row with a feature object in its extendedData
|
|
107
107
|
data.rowSet.rows.forEach((row, rowNumber) => {
|
|
108
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
109
108
|
const featureData = {};
|
|
110
109
|
row.cells.forEach(({ text }, columnNumber) => {
|
|
111
110
|
const bedColumn = bedColumns[columnNumber];
|
|
112
111
|
const val = bedColumn && bedColumn.dataType.type === 'Number' && text
|
|
113
|
-
? parseFloat(text)
|
|
112
|
+
? Number.parseFloat(text)
|
|
114
113
|
: text;
|
|
115
114
|
if (bedColumn) {
|
|
116
115
|
// a predefined column
|
|
@@ -48,6 +48,7 @@ function dataToSpreadsheetSnapshot(rows, options = {}) {
|
|
|
48
48
|
};
|
|
49
49
|
// process the column names row if present
|
|
50
50
|
const columnNames = {};
|
|
51
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
51
52
|
if (hasColumnNameLine && columnNameLineNumber !== undefined) {
|
|
52
53
|
const [colNamesRow] = rowSet.rows.splice(columnNameLineNumber - 1, 1);
|
|
53
54
|
if (colNamesRow) {
|