Skip to content

Commit

Permalink
Avoid cutting off import form of spreadsheet view, fix overflowed tex…
Browse files Browse the repository at this point in the history
…t in table header (#3610)
  • Loading branch information
cmdcolin committed Mar 24, 2023
1 parent ce67072 commit 01b7689
Show file tree
Hide file tree
Showing 8 changed files with 291 additions and 317 deletions.
120 changes: 49 additions & 71 deletions plugins/spreadsheet-view/src/SpreadsheetView/components/ColumnMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { observer } from 'mobx-react'
import { iterMap } from '@jbrowse/core/util'
import { Menu } from '@jbrowse/core/ui'
import { MenuItem } from '@jbrowse/core/ui/Menu'
import { SvgIcon } from '@mui/material'
import { SpreadsheetModel } from '../models/Spreadsheet'
import { SpreadsheetViewModel } from '../models/SpreadsheetView'

Expand Down Expand Up @@ -35,55 +34,45 @@ const ColumnMenu = observer(function ({
])
}

const filterMenuClick = () => {
viewModel.filterControls.addBlankColumnFilter(columnNumber)
}

const { dataTypeChoices } = spreadsheetModel

// make a Map of categoryName => [entry...]
const dataTypeTopLevelMenu = new Map()
type Record = (typeof dataTypeChoices)[0]
type RecordGroup = { isCategory: boolean; subMenuItems: Record[] }
const dataTypeTopLevelMenu = new Map<string, Record | RecordGroup>()
dataTypeChoices.forEach(dataTypeRecord => {
const { displayName, categoryName } = dataTypeRecord
if (categoryName) {
if (!dataTypeTopLevelMenu.has(categoryName)) {
dataTypeTopLevelMenu.set(categoryName, {
let entry = dataTypeTopLevelMenu.get(categoryName) as RecordGroup
if (!entry) {
entry = {
isCategory: true,
subMenuItems: [],
})
}
dataTypeTopLevelMenu.set(categoryName, entry)
}
dataTypeTopLevelMenu.get(categoryName).subMenuItems.push(dataTypeRecord)
entry.subMenuItems.push(dataTypeRecord)
} else {
dataTypeTopLevelMenu.set(displayName, dataTypeRecord)
}
})

const { columns, sortColumns } = spreadsheetModel
const dataType = currentColumnMenu && columns[columnNumber].dataType
const dataTypeName = (dataType && dataType.type) || ''
const dataTypeName = dataType?.type || ''
const dataTypeDisplayName =
(currentColumnMenu && columns[columnNumber].dataType.displayName) || ''

const isSortingAscending = Boolean(
sortColumns.length > 0 &&
currentColumnMenu &&
sortColumns.some(
col =>
col.columnNumber === currentColumnMenu.colNumber && !col.descending,
),
)
const isSortingDescending = Boolean(
sortColumns.length > 0 &&
currentColumnMenu &&
sortColumns.some(
col =>
col.columnNumber === currentColumnMenu.colNumber && col.descending,
),
)
function stopSortingClick() {
columnMenuClose()
spreadsheetModel.setSortColumns([])
}
const isSortingAscending =
!!currentColumnMenu &&
sortColumns.some(
c => c.columnNumber === currentColumnMenu.colNumber && !c.descending,
)
const isSortingDescending =
!!currentColumnMenu &&
sortColumns.some(
c => c.columnNumber === currentColumnMenu.colNumber && c.descending,
)

const menuItems = [
// top-level column menu
Expand All @@ -92,18 +81,21 @@ const ColumnMenu = observer(function ({
icon: SortIcon,
type: 'radio',
checked: isSortingAscending,
onClick: isSortingAscending
? stopSortingClick
: sortMenuClick.bind(null, false),
onClick: () => sortMenuClick(false),
},
{
label: 'Sort descending',
icon: SortIcon,
type: 'radio',
checked: isSortingDescending,
onClick: isSortingDescending
? stopSortingClick
: sortMenuClick.bind(null, true),
onClick: () => sortMenuClick(true),
},
{
label: 'No sort',
icon: SortIcon,
type: 'radio',
checked: !isSortingDescending && !isSortingAscending,
onClick: () => spreadsheetModel.setSortColumns([]),
},
// data type menu
{
Expand All @@ -112,58 +104,44 @@ const ColumnMenu = observer(function ({
subMenu: iterMap(
dataTypeTopLevelMenu.entries(),
([displayName, record]) => {
const { subMenuItems, typeName } = record
if (typeName) {
const menuEntry = {
if ('typeName' in record && record.typeName) {
const { typeName } = record
return {
label: displayName || typeName,
icon: undefined as typeof SvgIcon | undefined,
onClick: () => {
spreadsheetModel.setColumnType(columnNumber, typeName)
},
}
if (dataTypeName === typeName) {
menuEntry.icon = CheckIcon
icon: dataTypeName === typeName ? CheckIcon : undefined,
onClick: () =>
spreadsheetModel.setColumnType(columnNumber, typeName),
}
return menuEntry
}
if (subMenuItems) {
} else if ('subMenuItems' in record && record.subMenuItems) {
const { subMenuItems } = record
return {
label: displayName,
icon: subMenuItems.some(
(i: { typeName: string }) => i.typeName === dataTypeName,
)
icon: subMenuItems.some(i => i.typeName === dataTypeName)
? CheckIcon
: undefined,
subMenu: subMenuItems.map(
({
typeName: subTypeName,
displayName: subDisplayName,
}: {
typeName: string
displayName: string
}) => ({
label: subDisplayName,
icon: subTypeName === dataTypeName ? CheckIcon : undefined,
onClick: () => {
spreadsheetModel.setColumnType(columnNumber, subTypeName)
},
}),
),
subMenu: subMenuItems.map(({ typeName, displayName }) => ({
label: displayName,
icon: typeName === dataTypeName ? CheckIcon : undefined,
onClick: () =>
spreadsheetModel.setColumnType(columnNumber, typeName),
})),
}
} else {
return null
}
return null
},
).filter(Boolean),
},
] as MenuItem[]

// don't display the filter item if this data type doesn't have filtering
// implemented
if (dataType && dataType.hasFilter) {
if (dataType?.hasFilter) {
menuItems.push({
label: 'Create filter',
icon: FilterListIcon,
onClick: filterMenuClick.bind(null, true),
onClick: () =>
viewModel.filterControls.addBlankColumnFilter(columnNumber),
})
}

Expand Down
84 changes: 40 additions & 44 deletions plugins/spreadsheet-view/src/SpreadsheetView/components/DataRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,51 +16,47 @@ import CellData from './CellData'
type SpreadsheetModel = Instance<typeof SpreadsheetStateModel>
type RowModel = Instance<typeof RowStateModel>

const useStyles = makeStyles()(theme => {
const { palette } = theme
return {
rowNumCell: {
textAlign: 'left',
border: `1px solid ${palette.action.disabledBackground}`,
position: 'relative',
padding: '0 2px 0 0',
whiteSpace: 'nowrap',
userSelect: 'none',
},
rowNumber: {
fontWeight: 'normal',
display: 'inline-block',
flex: 'none',
paddingRight: '20px',
margin: 0,
whiteSpace: 'nowrap',
},
rowMenuButton: {
padding: 0,
margin: 0,
position: 'absolute',
right: 0,
display: 'inline-block',
whiteSpace: 'nowrap',
flex: 'none',
},
rowMenuButtonIcon: {},
rowSelector: {
position: 'relative',
top: '-2px',
margin: 0,
padding: '0 0.2rem',
},
const useStyles = makeStyles()(theme => ({
rowNumCell: {
textAlign: 'left',
border: `1px solid ${theme.palette.action.disabledBackground}`,
position: 'relative',
padding: '0 2px 0 0',
whiteSpace: 'nowrap',
userSelect: 'none',
},
rowNumber: {
fontWeight: 'normal',
display: 'inline-block',
flex: 'none',
paddingRight: '20px',
margin: 0,
whiteSpace: 'nowrap',
},
rowMenuButton: {
padding: 0,
margin: 0,
position: 'absolute',
right: 0,
display: 'inline-block',
whiteSpace: 'nowrap',
flex: 'none',
},
rowMenuButtonIcon: {},
rowSelector: {
position: 'relative',
top: '-2px',
margin: 0,
padding: '0 0.2rem',
},

dataRowSelected: {
dataRowSelected: {
background: indigo[100],
'& th': {
background: indigo[100],
'& th': {
background: indigo[100],
},
},
emptyMessage: { captionSide: 'bottom' },
}
})
},
}))

const DataRow = observer(function ({
rowModel,
Expand All @@ -86,7 +82,7 @@ const DataRow = observer(function ({

return (
<tr className={rowClass}>
<th className={classes.rowNumCell} onClick={labelClick}>
<td className={classes.rowNumCell} onClick={labelClick}>
{hideRowSelection ? (
<FormControlLabel
className={classes.rowNumber}
Expand All @@ -113,7 +109,7 @@ const DataRow = observer(function ({
>
<ArrowDropDown className={classes.rowMenuButtonIcon} />
</IconButton>
</th>
</td>
{columnDisplayOrder.map(colNumber => (
<td key={colNumber}>
<CellData
Expand Down
Loading

0 comments on commit 01b7689

Please sign in to comment.