Option to toggle fields in songs, albums & artists (#923)

* Add toggleColumns

- Add logic for toggling columns
- Add MenuComponent + useSelectedFields hook

* Refactoring

* eslint-fixes

* Typo

* skip menu in albumGridView

* add omittedFields

* Add toggling for playlists and albumSong

* Refactoring

* defaultProps - fix

* Add toggling for PlaylistSongs

* remove accidental console log

* Refactoring for future compatibility

* Hide ToggleMenu in albumGridView

* Add TopBarComponent in ToggleFieldsMenu

* Add defaultOff for useSelectedFields

* Fix edge case

* eslint fix

* Refactoring

* Add propType for forwardRef

* Fix issues

* add translation for grid and table

* add translation for grid and table

* Ignore menuBtn for spotify-ish and Ligera themes

* hide bpm by default in playlistSongs

* Add memoization

* Default album view must be Grid

Co-authored-by: Deluan <deluan@navidrome.org>
This commit is contained in:
Aldrin Jenson
2021-05-24 20:39:06 +05:30
committed by GitHub
parent 6a17717e30
commit cf8ee251ee
22 changed files with 681 additions and 215 deletions
+109
View File
@@ -0,0 +1,109 @@
import React, { useState } from 'react'
import PropTypes from 'prop-types'
import IconButton from '@material-ui/core/IconButton'
import Menu from '@material-ui/core/Menu'
import MenuItem from '@material-ui/core/MenuItem'
import { makeStyles, Typography } from '@material-ui/core'
import MoreVertIcon from '@material-ui/icons/MoreVert'
import Checkbox from '@material-ui/core/Checkbox'
import { useDispatch, useSelector } from 'react-redux'
import { useTranslate } from 'react-admin'
import { setToggleableFields } from '../actions'
const useStyles = makeStyles({
menuIcon: {
position: 'relative',
top: '-0.5em',
},
menu: {
width: '24ch',
},
columns: {
maxHeight: '21rem',
overflow: 'auto',
},
title: {
margin: '1rem',
},
})
const ToggleFieldsMenu = ({ resource, topbarComponent: TopBarComponent }) => {
const [anchorEl, setAnchorEl] = useState(null)
const dispatch = useDispatch()
const translate = useTranslate()
const toggleableColumns = useSelector(
(state) => state.settings.toggleableFields[resource]
)
const omittedColumns =
useSelector((state) => state.settings.omittedFields[resource]) || []
const classes = useStyles()
const open = Boolean(anchorEl)
const handleOpen = (event) => {
setAnchorEl(event.currentTarget)
}
const handleClose = () => {
setAnchorEl(null)
}
const handleClick = (selectedColumn) => {
dispatch(
setToggleableFields({
[resource]: {
...toggleableColumns,
[selectedColumn]: !toggleableColumns[selectedColumn],
},
})
)
}
return (
<div className={classes.menuIcon}>
<IconButton
aria-label="more"
aria-controls="long-menu"
aria-haspopup="true"
onClick={handleOpen}
>
<MoreVertIcon />
</IconButton>
<Menu
id="long-menu"
anchorEl={anchorEl}
keepMounted
open={open}
onClose={handleClose}
classes={{
paper: classes.menu,
}}
>
{TopBarComponent && <TopBarComponent />}
{toggleableColumns ? (
<div>
<Typography className={classes.title}>
{translate('ra.toggleFieldsMenu.columnsToDisplay')}
</Typography>
<div className={classes.columns}>
{Object.entries(toggleableColumns).map(([key, val]) =>
!omittedColumns.includes(key) ? (
<MenuItem key={key} onClick={() => handleClick(key)}>
<Checkbox checked={val} />
{translate(`resources.${resource}.fields.${key}`)}
</MenuItem>
) : null
)}
</div>
</div>
) : null}
</Menu>
</div>
)
}
export default ToggleFieldsMenu
ToggleFieldsMenu.propTypes = {
resource: PropTypes.string.isRequired,
topbarComponent: PropTypes.elementType,
}