From 5712b47e7b8648504fd0bc4047863d57a5d711bf Mon Sep 17 00:00:00 2001 From: Colin Date: Thu, 23 May 2024 11:14:28 -0400 Subject: [PATCH] Remove resize bar usage --- .../BaseFeatureDetail/DataGridDetails.tsx | 14 +- packages/core/ui/ResizeBar.tsx | 109 ----------- .../components/faceted/FacetedSelector.tsx | 60 ++++--- .../facetedModel.ts | 51 +----- .../components/BookmarkGrid.tsx | 170 +++++++++--------- .../src/VariantFeatureWidget/AnnotGrid.tsx | 29 +-- .../VariantSampleGrid.tsx | 41 ++--- .../StartScreen/RecentSessionList.tsx | 27 +-- 8 files changed, 147 insertions(+), 354 deletions(-) delete mode 100644 packages/core/ui/ResizeBar.tsx diff --git a/packages/core/BaseFeatureWidget/BaseFeatureDetail/DataGridDetails.tsx b/packages/core/BaseFeatureWidget/BaseFeatureDetail/DataGridDetails.tsx index 7e4cee46d3..852d4201d3 100644 --- a/packages/core/BaseFeatureWidget/BaseFeatureDetail/DataGridDetails.tsx +++ b/packages/core/BaseFeatureWidget/BaseFeatureDetail/DataGridDetails.tsx @@ -5,9 +5,7 @@ import { Checkbox, FormControlLabel, Typography } from '@mui/material' // locals import { measureGridWidth, getStr } from '../../util' -import ResizeBar from '../../ui/ResizeBar' import FieldName from './FieldName' -import { useResizeBar } from '../../ui/useResizeBar' import { SanitizedHTML } from '../../ui' const useStyles = makeStyles()(theme => ({ @@ -38,7 +36,6 @@ export default function DataGridDetails({ value: Record[] }) { const { classes } = useStyles() - const { ref, scrollLeft } = useResizeBar() const [checked, setChecked] = useState(false) const keys = Object.keys(value[0]).sort() const unionKeys = new Set(keys) @@ -67,9 +64,7 @@ export default function DataGridDetails({ } else { colNames = [...unionKeys] } - const [widths, setWidths] = useState( - colNames.map(e => measureGridWidth(rows.map(r => r[e]))), - ) + const widths = colNames.map(e => measureGridWidth(rows.map(r => r[e]))) if (unionKeys.size < keys.length + 5) { return ( @@ -84,12 +79,7 @@ export default function DataGridDetails({ } label={Show options} /> -
- +
({ - resizeBar: { - background: theme.palette.action.disabledBackground, - height: 12, - position: 'relative', - overflow: 'hidden', - }, - tick: { - position: 'absolute', - height: '100%', - pointerEvents: 'none', - background: theme.palette.action.disabled, - width: 1, - }, - hiddenTick: { - position: 'absolute', - height: '100%', - width: 5, - }, -})) - -function Tick({ - left, - scrollLeft, - idx, - onDrag, - onMouseDown, -}: { - idx: number - left: number - scrollLeft: number - onMouseDown: (event: React.MouseEvent) => void - onDrag: ( - lastFrameDistance: number, - totalDistance: number, - idx: number, - ) => void -}) { - const { classes } = useStyles() - const onDragCallback = useCallback( - (lastFrameDistance: number, totalDistance: number) => - onDrag(lastFrameDistance, totalDistance, idx), - [idx, onDrag], - ) - - // has an invisible wider than tick mark (1px) clickable area (5px) - return ( - <> - -
- - ) -} - -export default function ResizeBar({ - widths, - setWidths, - checkbox, - scrollLeft = 0, -}: { - widths: number[] - setWidths: (arg: number[]) => void - checkbox?: boolean - scrollLeft?: number -}) { - const { classes } = useStyles() - const offsets = [] as number[] - const [initial, setInitial] = useState() - let init = checkbox ? 52 : 0 - for (let i = 0; i < widths.length; i++) { - const width = widths[i] - offsets[i] = width + init - init += width - } - - return ( -
- {offsets.map((left, i) => ( - { - setInitial([...widths]) - }} - left={i === offsets.length - 1 ? left - 3 : left} - onDrag={(_: number, totalDistance: number, idx: number) => { - const newWidths = [...widths] - // mui doesn't allow columns smaller than 50 - newWidths[idx] = Math.max(initial![idx] - totalDistance, 50) - setWidths(newWidths) - }} - idx={i} - scrollLeft={scrollLeft} - /> - ))} -
- ) -} diff --git a/plugins/data-management/src/HierarchicalTrackSelectorWidget/components/faceted/FacetedSelector.tsx b/plugins/data-management/src/HierarchicalTrackSelectorWidget/components/faceted/FacetedSelector.tsx index 50c074b4eb..36837d20f8 100644 --- a/plugins/data-management/src/HierarchicalTrackSelectorWidget/components/faceted/FacetedSelector.tsx +++ b/plugins/data-management/src/HierarchicalTrackSelectorWidget/components/faceted/FacetedSelector.tsx @@ -7,10 +7,8 @@ import { DataGrid, GridColDef, GridToolbar } from '@mui/x-data-grid' // jbrowse import { ResizeHandle } from '@jbrowse/core/ui' import SanitizedHTML from '@jbrowse/core/ui/SanitizedHTML' -import ResizeBar from '@jbrowse/core/ui/ResizeBar' -import { getEnv, useDebounce } from '@jbrowse/core/util' +import { getEnv, measureGridWidth } from '@jbrowse/core/util' import { AnyConfigurationModel } from '@jbrowse/core/configuration' -import { useResizeBar } from '@jbrowse/core/ui/useResizeBar' import { makeStyles } from 'tss-react/mui' // locals @@ -57,14 +55,42 @@ const FacetedSelector = observer(function FacetedSelector({ filteredNonMetadataKeys, filteredMetadataKeys, visible, - widths, } = faceted const { pluginManager } = getEnv(model) - const { ref, scrollLeft } = useResizeBar() - const widthsDebounced = useDebounce(widths, 200) type T = GridColDef<(typeof filteredRows)[0]> + const widths = { + name: + measureGridWidth( + rows.map(r => r.name), + { maxWidth: 500, stripHTML: true }, + ) + 15, + ...Object.fromEntries( + filteredNonMetadataKeys + .filter(f => visible[f]) + .map(e => [ + e, + measureGridWidth( + rows.map(r => r[e as keyof typeof r] as string), + { maxWidth: 400, stripHTML: true }, + ), + ]), + ), + ...Object.fromEntries( + filteredMetadataKeys + .filter(f => visible['metadata.' + f]) + .map(e => { + return [ + 'metadata.' + e, + measureGridWidth( + rows.map(r => r.metadata[e]), + { maxWidth: 400, stripHTML: true }, + ), + ] + }), + ), + } as Record const columns: T[] = [ { field: 'name', @@ -79,12 +105,12 @@ const FacetedSelector = observer(function FacetedSelector({
) }, - width: widthsDebounced.name ?? 100, + width: widths.name ?? 100, }, ...filteredNonMetadataKeys.map(e => { return { field: e, - width: widthsDebounced[e] ?? 100, + width: widths[e] ?? 100, renderCell: params => { const val = params.value return val ? ( @@ -101,7 +127,7 @@ const FacetedSelector = observer(function FacetedSelector({ headerName: ['name', ...filteredNonMetadataKeys].includes(e) ? `${e} (from metadata)` : e, - width: widthsDebounced['metadata.' + e] ?? 100, + width: widths['metadata.' + e] ?? 100, valueGetter: (_, row) => `${row.metadata[e]}`, renderCell: params => { const val = params.value @@ -119,7 +145,6 @@ const FacetedSelector = observer(function FacetedSelector({ <>
- f ?? 100)} - setWidths={newWidths => - faceted.setWidths( - Object.fromEntries( - Object.entries(widths).map((entry, idx) => [ - entry[0], - newWidths[idx], - ]), - ), - ) - } - scrollLeft={scrollLeft} - /> ({ visible: {} as Record, - widths: {} as Record, useShoppingCart: false, filters: observable.map(), })) @@ -193,12 +188,7 @@ export function facetedStateTreeF() { setVisible(args: Record) { self.visible = args }, - /** - * #action - */ - setWidths(args: Record) { - self.widths = args - }, + afterAttach() { addDisposer( self, @@ -206,43 +196,6 @@ export function facetedStateTreeF() { this.setVisible(Object.fromEntries(self.fields.map(c => [c, true]))) }), ) - - addDisposer( - self, - autorun(() => { - this.setWidths({ - name: - measureGridWidth( - self.rows.map(r => r.name), - { maxWidth: 500, stripHTML: true }, - ) + 15, - ...Object.fromEntries( - self.filteredNonMetadataKeys - .filter(f => self.visible[f]) - .map(e => [ - e, - measureGridWidth( - self.rows.map(r => r[e as keyof typeof r] as string), - { maxWidth: 400, stripHTML: true }, - ), - ]), - ), - ...Object.fromEntries( - self.filteredMetadataKeys - .filter(f => self.visible['metadata.' + f]) - .map(e => { - return [ - 'metadata.' + e, - measureGridWidth( - self.rows.map(r => r.metadata[e]), - { maxWidth: 400, stripHTML: true }, - ), - ] - }), - ), - }) - }), - ) }, })) } diff --git a/plugins/grid-bookmark/src/GridBookmarkWidget/components/BookmarkGrid.tsx b/plugins/grid-bookmark/src/GridBookmarkWidget/components/BookmarkGrid.tsx index 8548af5395..30f3a63197 100644 --- a/plugins/grid-bookmark/src/GridBookmarkWidget/components/BookmarkGrid.tsx +++ b/plugins/grid-bookmark/src/GridBookmarkWidget/components/BookmarkGrid.tsx @@ -1,4 +1,4 @@ -import React, { lazy, useState } from 'react' +import React, { lazy } from 'react' import { observer } from 'mobx-react' import { Link } from '@mui/material' import { makeStyles } from 'tss-react/mui' @@ -9,8 +9,6 @@ import { measureGridWidth, measureText, } from '@jbrowse/core/util' -import { useResizeBar } from '@jbrowse/core/ui/useResizeBar' -import ResizeBar from '@jbrowse/core/ui/ResizeBar' import ColorPicker from '@jbrowse/core/ui/ColorPicker' // locals @@ -38,7 +36,6 @@ const BookmarkGrid = observer(function ({ model: GridBookmarkModel }) { const { classes, cx } = useStyles() - const { ref, scrollLeft } = useResizeBar() const { bookmarks, bookmarksWithValidAssemblies, @@ -61,7 +58,7 @@ const BookmarkGrid = observer(function ({ } }) - const [widths, setWidths] = useState([ + const widths = [ 50, Math.max( measureText('Bookmark link', 12) + 30, @@ -76,93 +73,86 @@ const BookmarkGrid = observer(function ({ measureGridWidth(rows.map(row => row.assemblyName)), ), 100, - ]) + ] return ( -
- - ( - { - event.preventDefault() - const { views } = session - await navToBookmark(value, row.assemblyName, views, model) - }} - > - {value} - - ), - }, - { - field: 'label', - headerName: 'Label', - width: widths[2], - editable: true, - }, - { - field: 'assemblyName', - headerName: 'Assembly', - width: widths[3], - }, - { - field: 'highlight', - headerName: 'Highlight', - width: widths[4], - renderCell: ({ value, row }) => ( - { - model.updateBookmarkHighlight(row, event) - }} - /> - ), - }, - ]} - onCellDoubleClick={({ row }) => { - getSession(model).queueDialog(onClose => [ - EditBookmarkLabelDialog, - { onClose, model, dialogRow: row }, - ]) - }} - processRowUpdate={row => { - const target = rows[row.id] - model.updateBookmarkLabel(target, row.label) - return row - }} - onProcessRowUpdateError={e => session.notifyError(`${e}`, e)} - checkboxSelection - onRowSelectionModelChange={newRowSelectionModel => { - if (bookmarksWithValidAssemblies.length > 0) { - model.setSelectedBookmarks( - newRowSelectionModel.map(value => ({ - ...rows[value as number], - })), - ) - } - }} - rowSelectionModel={selectedBookmarks.map(r => r.id)} - disableRowSelectionOnClick - /> -
+ ( + { + event.preventDefault() + const { views } = session + await navToBookmark(value, row.assemblyName, views, model) + }} + > + {value} + + ), + }, + { + field: 'label', + headerName: 'Label', + width: widths[2], + editable: true, + }, + { + field: 'assemblyName', + headerName: 'Assembly', + width: widths[3], + }, + { + field: 'highlight', + headerName: 'Highlight', + width: widths[4], + renderCell: ({ value, row }) => ( + { + model.updateBookmarkHighlight(row, event) + }} + /> + ), + }, + ]} + onCellDoubleClick={({ row }) => { + getSession(model).queueDialog(onClose => [ + EditBookmarkLabelDialog, + { onClose, model, dialogRow: row }, + ]) + }} + processRowUpdate={row => { + const target = rows[row.id] + model.updateBookmarkLabel(target, row.label) + return row + }} + onProcessRowUpdateError={e => session.notifyError(`${e}`, e)} + checkboxSelection + onRowSelectionModelChange={newRowSelectionModel => { + if (bookmarksWithValidAssemblies.length > 0) { + model.setSelectedBookmarks( + newRowSelectionModel.map(value => ({ + ...rows[value as number], + })), + ) + } + }} + rowSelectionModel={selectedBookmarks.map(r => r.id)} + disableRowSelectionOnClick + /> ) }) diff --git a/plugins/variants/src/VariantFeatureWidget/AnnotGrid.tsx b/plugins/variants/src/VariantFeatureWidget/AnnotGrid.tsx index d2c619e4f5..493eb2bd16 100644 --- a/plugins/variants/src/VariantFeatureWidget/AnnotGrid.tsx +++ b/plugins/variants/src/VariantFeatureWidget/AnnotGrid.tsx @@ -6,9 +6,7 @@ import { GridValidRowModel, } from '@mui/x-data-grid' import { Checkbox, FormControlLabel, Typography } from '@mui/material' -import ResizeBar from '@jbrowse/core/ui/ResizeBar' import { measureGridWidth } from '@jbrowse/core/util' -import { useResizeBar } from '@jbrowse/core/ui/useResizeBar' export default function VariantAnnotPanel({ rows, @@ -17,14 +15,11 @@ export default function VariantAnnotPanel({ rows: GridValidRowModel[] columns: GridColDef[] }) { - const { ref, scrollLeft } = useResizeBar() const [checked, setChecked] = useState(false) - const [widths, setWidths] = useState( - columns.map(e => measureGridWidth(rows.map(r => r[e.field]))), - ) + const widths = columns.map(e => measureGridWidth(rows.map(r => r[e.field]))) return rows.length ? ( -
+
Show options} /> -
- - ({ ...c, width: widths[i] }))} - slots={{ toolbar: checked ? GridToolbar : null }} - /> -
+ + ({ ...c, width: widths[i] }))} + slots={{ toolbar: checked ? GridToolbar : null }} + />
) : null } diff --git a/plugins/variants/src/VariantFeatureWidget/VariantSampleGrid.tsx b/plugins/variants/src/VariantFeatureWidget/VariantSampleGrid.tsx index 331c172468..8d8a5054f8 100644 --- a/plugins/variants/src/VariantFeatureWidget/VariantSampleGrid.tsx +++ b/plugins/variants/src/VariantFeatureWidget/VariantSampleGrid.tsx @@ -10,8 +10,6 @@ import { import { DataGrid, GridToolbar } from '@mui/x-data-grid' import { BaseCard } from '@jbrowse/core/BaseFeatureWidget/BaseFeatureDetail' import { measureGridWidth, SimpleFeatureSerialized } from '@jbrowse/core/util' -import ResizeBar from '@jbrowse/core/ui/ResizeBar' -import { useResizeBar } from '@jbrowse/core/ui/useResizeBar' interface Entry { sample: string @@ -58,7 +56,6 @@ export default function VariantSamples(props: { descriptions?: { FORMAT?: Record } | null }) { const { feature, descriptions = {} } = props - const { ref, scrollLeft } = useResizeBar() const [filter, setFilter] = useState({}) const samples = (feature.samples || {}) as Record const preFilteredRows = Object.entries(samples) @@ -97,9 +94,7 @@ export default function VariantSamples(props: { const keys = ['sample', ...Object.keys(preFilteredRows[0]?.[1] || {})] const [checked, setChecked] = useState(false) - const [widths, setWidths] = useState( - keys.map(e => measureGridWidth(rows.map(r => r[e]))), - ) + const widths = keys.map(e => measureGridWidth(rows.map(r => r[e]))) const columns = keys.map((field, index) => ({ field, description: descriptions?.FORMAT?.[field]?.Description, @@ -127,26 +122,20 @@ export default function VariantSamples(props: { filter={filter} /> ) : null} -
- - -
+ + ) } diff --git a/products/jbrowse-desktop/src/components/StartScreen/RecentSessionList.tsx b/products/jbrowse-desktop/src/components/StartScreen/RecentSessionList.tsx index ba431b5b60..fb0f366435 100644 --- a/products/jbrowse-desktop/src/components/StartScreen/RecentSessionList.tsx +++ b/products/jbrowse-desktop/src/components/StartScreen/RecentSessionList.tsx @@ -1,13 +1,10 @@ -import React, { useState } from 'react' +import React from 'react' import { IconButton, Link, Tooltip } from '@mui/material' import { makeStyles } from 'tss-react/mui' import { DataGrid } from '@mui/x-data-grid' import PluginManager from '@jbrowse/core/PluginManager' import { format } from 'timeago.js' -import { useResizeBar } from '@jbrowse/core/ui/useResizeBar' -import ResizeBar from '@jbrowse/core/ui/ResizeBar' - // icons import EditIcon from '@mui/icons-material/Edit' @@ -57,7 +54,6 @@ export default function RecentSessionsList({ sessions: RecentSessionData[] }) { const { classes, cx } = useStyles() - const { ref, scrollLeft } = useResizeBar() const now = Date.now() const oneDayLength = 24 * 60 * 60 * 1000 @@ -79,7 +75,7 @@ export default function RecentSessionsList({ }) const arr = ['name', 'path', 'lastModified'] - const [widths, setWidths] = useState({ + const widths = { rename: 40, ...Object.fromEntries( arr.map(e => [ @@ -90,25 +86,10 @@ export default function RecentSessionsList({ ) + 20, ]), ), - } as Record) + } as Record return ( -
- f ?? 100)} - setWidths={newWidths => - setWidths( - Object.fromEntries( - Object.entries(widths).map((entry, idx) => [ - entry[0], - newWidths[idx], - ]), - ), - ) - } - scrollLeft={scrollLeft} - /> +