diff --git a/plugins/variants/src/MultiLinearVariantDisplay/components/Crosshair.tsx b/plugins/variants/src/MultiLinearVariantDisplay/components/Crosshair.tsx index 7c32b86b62..fc04f5e498 100644 --- a/plugins/variants/src/MultiLinearVariantDisplay/components/Crosshair.tsx +++ b/plugins/variants/src/MultiLinearVariantDisplay/components/Crosshair.tsx @@ -2,9 +2,10 @@ import { getContainingView } from '@jbrowse/core/util' import { observer } from 'mobx-react' import { makeStyles } from 'tss-react/mui' +import MultiVariantTooltip from '../../shared/MultiVariantTooltip' + import type { MultiLinearVariantDisplayModel } from '../model' import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view' -import MultiVariantTooltip from '../../shared/MultiVariantTooltip' const useStyles = makeStyles()({ rel: { diff --git a/plugins/variants/src/shared/SourcesDataGrid.tsx b/plugins/variants/src/shared/SourcesDataGrid.tsx new file mode 100644 index 0000000000..246f29915d --- /dev/null +++ b/plugins/variants/src/shared/SourcesDataGrid.tsx @@ -0,0 +1,127 @@ +import { useState } from 'react' + +import { SanitizedHTML } from '@jbrowse/core/ui' +import ColorPicker from '@jbrowse/core/ui/ColorPicker' +import { getStr, measureGridWidth } from '@jbrowse/core/util' +import { DataGrid } from '@mui/x-data-grid' +import { makeStyles } from 'tss-react/mui' + +import type { Source } from '../types' +import type { GridColDef } from '@mui/x-data-grid' + +const useStyles = makeStyles()({ + cell: { + whiteSpace: 'nowrap', + overflow: 'hidden', + textOverflow: 'ellipsis', + }, +}) + +interface SortField { + idx: number + field: string | null +} + +export default function SourcesDataGrid({ + rows, + onChange, + setSelected, +}: { + rows: Source[] + onChange: (arg: Source[]) => void + setSelected: (arg: string[]) => void +}) { + const { classes } = useStyles() + const { + id: _id, + name: _name, + color: _color, + baseUri: _baseUri, + HP: _HP, + ...rest + } = rows[0]! + const [currSort, setCurrSort] = useState({ + idx: 0, + field: null, + }) + + return ( +
+ { + setSelected(arg as string[]) + }} + rows={rows} + rowHeight={25} + columnHeaderHeight={33} + columns={[ + { + field: 'color', + headerName: 'Color', + renderCell: params => { + const { value, id } = params + return ( + { + const elt = rows.find(f => f.name === id) + if (elt) { + elt.color = c + } + onChange([...rows]) + }} + /> + ) + }, + }, + { + field: 'name', + headerName: 'Name', + width: measureGridWidth(rows.map(r => r.name)), + }, + ...Object.keys(rest).map( + val => + ({ + field: val, + renderCell: ({ value }) => ( +
+ +
+ ), + width: measureGridWidth( + rows.map(r => `${r[val as keyof Source]}`), + ), + }) satisfies GridColDef<(typeof rows)[0]>, + ), + ]} + sortModel={ + [ + /* we control the sort as a controlled component using + * onSortModelChange */ + ] + } + onSortModelChange={args => { + const sort = args[0] + // this idx%2 flip flops the sorting order, we could inspect args + // for sort direction asc or desc but this is just a simplified + // thing since we are controlling sort instead of the default data + // grid sort anyways + const idx = (currSort.idx + 1) % 2 + const field = sort!.field || currSort.field + setCurrSort({ idx, field }) + onChange( + field + ? [...rows].sort((a, b) => { + const aa = getStr(a[field as keyof Source]) + const bb = getStr(b[field as keyof Source]) + return idx === 1 ? aa.localeCompare(bb) : bb.localeCompare(aa) + }) + : rows, + ) + }} + /> +
+ ) +} diff --git a/plugins/variants/src/shared/SourcesGrid.tsx b/plugins/variants/src/shared/SourcesGrid.tsx index a862e6f0b2..731dff26fa 100644 --- a/plugins/variants/src/shared/SourcesGrid.tsx +++ b/plugins/variants/src/shared/SourcesGrid.tsx @@ -1,30 +1,9 @@ import { useState } from 'react' -import { SanitizedHTML } from '@jbrowse/core/ui' -import ColorPicker from '@jbrowse/core/ui/ColorPicker' -import { getStr, measureGridWidth } from '@jbrowse/core/util' - -import { DataGrid } from '@mui/x-data-grid' -import { makeStyles } from 'tss-react/mui' - -import type { Source } from '../types' -import type { GridColDef } from '@mui/x-data-grid' +import SourcesDataGrid from './SourcesDataGrid' import SourcesGridHeader from './SourcesGridHeader' -// icons - -const useStyles = makeStyles()({ - cell: { - whiteSpace: 'nowrap', - overflow: 'hidden', - textOverflow: 'ellipsis', - }, -}) - -interface SortField { - idx: number - field: string | null -} +import type { Source } from '../types' function SourcesGrid({ rows, @@ -35,20 +14,7 @@ function SourcesGrid({ onChange: (arg: Source[]) => void showTips: boolean }) { - const { classes } = useStyles() const [selected, setSelected] = useState([] as string[]) - const { - id: _id, - name: _name, - color: _color, - baseUri: _baseUri, - HP: _HP, - ...rest - } = rows[0]! - const [currSort, setCurrSort] = useState({ - idx: 0, - field: null, - }) return (
@@ -58,86 +24,11 @@ function SourcesGrid({ showTips={showTips} onChange={onChange} /> -
- row.name} - checkboxSelection - disableRowSelectionOnClick - onRowSelectionModelChange={arg => { - setSelected(arg as string[]) - }} - rows={rows} - rowHeight={25} - columnHeaderHeight={33} - columns={[ - { - field: 'color', - headerName: 'Color', - renderCell: params => { - const { value, id } = params - return ( - { - const elt = rows.find(f => f.name === id) - if (elt) { - elt.color = c - } - onChange([...rows]) - }} - /> - ) - }, - }, - { - field: 'name', - headerName: 'Name', - width: measureGridWidth(rows.map(r => r.name)), - }, - ...Object.keys(rest).map( - val => - ({ - field: val, - renderCell: ({ value }) => ( -
- -
- ), - width: measureGridWidth( - rows.map(r => `${r[val as keyof Source]}`), - ), - }) satisfies GridColDef<(typeof rows)[0]>, - ), - ]} - sortModel={ - [ - /* we control the sort as a controlled component using - * onSortModelChange */ - ] - } - onSortModelChange={args => { - const sort = args[0] - // this idx%2 flip flops the sorting order, we could inspect args - // for sort direction asc or desc but this is just a simplified - // thing since we are controlling sort instead of the default data - // grid sort anyways - const idx = (currSort.idx + 1) % 2 - const field = sort!.field || currSort.field - setCurrSort({ idx, field }) - onChange( - field - ? [...rows].sort((a, b) => { - const aa = getStr(a[field as keyof Source]) - const bb = getStr(b[field as keyof Source]) - return idx === 1 - ? aa.localeCompare(bb) - : bb.localeCompare(aa) - }) - : rows, - ) - }} - /> -
+
) } diff --git a/plugins/variants/src/types.ts b/plugins/variants/src/types.ts index 558a3ee531..7904e918c2 100644 --- a/plugins/variants/src/types.ts +++ b/plugins/variants/src/types.ts @@ -5,6 +5,7 @@ export interface Source { color?: string group?: string HP?: number + id?: string [key: string]: unknown }