feat: custom SimpleList, to allow onClick handle

This commit is contained in:
Deluan 2020-02-07 15:35:05 -05:00
parent f0e7f3ef25
commit a50735a94c
5 changed files with 171 additions and 10 deletions

View File

@ -1,10 +1,12 @@
import React from 'react'
import { SimpleList, useGetList } from 'react-admin'
import { DurationField, PlayButton } from '../common'
import { addTrack } from '../player'
import { useGetList } from 'react-admin'
import { DurationField, PlayButton, SimpleList } from '../common'
import { addTrack, setTrack } from '../player'
import AddIcon from '@material-ui/icons/Add'
import { useDispatch } from 'react-redux'
const AlbumSongList = (props) => {
const dispatch = useDispatch()
const { record } = props
const { data, total, loading, error } = useGetList(
'song',
@ -39,7 +41,7 @@ const AlbumSongList = (props) => {
r.albumArtist && r.artist !== r.albumArtist ? r.artist : ''
}
tertiaryText={(r) => <DurationField record={r} source={'duration'} />}
linkType={false}
linkType={(id, basePath, record) => dispatch(setTrack(record))}
/>
)
}

View File

@ -17,7 +17,10 @@ const PlayButton = ({
return (
<IconButton
onClick={() => dispatch(action(record))}
onClick={(e) => {
e.stopPropagation()
dispatch(action(record))
}}
{...rest}
size={'small'}
>

149
ui/src/common/SimpleList.js Normal file
View File

@ -0,0 +1,149 @@
import React from 'react'
import PropTypes from 'prop-types'
import Avatar from '@material-ui/core/Avatar'
import List from '@material-ui/core/List'
import ListItem from '@material-ui/core/ListItem'
import ListItemAvatar from '@material-ui/core/ListItemAvatar'
import ListItemIcon from '@material-ui/core/ListItemIcon'
import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'
import ListItemText from '@material-ui/core/ListItemText'
import { makeStyles } from '@material-ui/core/styles'
import { Link } from 'react-router-dom'
import { linkToRecord, sanitizeListRestProps } from 'ra-core'
const useStyles = makeStyles(
{
link: {
textDecoration: 'none',
color: 'inherit'
},
tertiary: { float: 'right', opacity: 0.541176 }
},
{ name: 'RaSimpleList' }
)
const LinkOrNot = ({
classes: classesOverride,
linkType,
basePath,
id,
record,
children
}) => {
const classes = useStyles({ classes: classesOverride })
return linkType === 'edit' || linkType === true ? (
<Link to={linkToRecord(basePath, id)} className={classes.link}>
{children}
</Link>
) : linkType === 'show' ? (
<Link to={`${linkToRecord(basePath, id)}/show`} className={classes.link}>
{children}
</Link>
) : typeof linkType === 'function' ? (
<span onClick={() => linkType(id, basePath, record)}>{children}</span>
) : (
<span>{children}</span>
)
}
const SimpleList = ({
basePath,
className,
classes: classesOverride,
data,
hasBulkActions,
ids,
loading,
leftAvatar,
leftIcon,
linkType,
onToggleItem,
primaryText,
rightAvatar,
rightIcon,
secondaryText,
selectedIds,
tertiaryText,
total,
...rest
}) => {
const classes = useStyles({ classes: classesOverride })
return (
(loading || total > 0) && (
<List className={className} {...sanitizeListRestProps(rest)}>
{ids.map((id) => (
<LinkOrNot
linkType={linkType}
basePath={basePath}
id={id}
key={id}
record={data[id]}
>
<ListItem button={!!linkType}>
{leftIcon && (
<ListItemIcon>{leftIcon(data[id], id)}</ListItemIcon>
)}
{leftAvatar && (
<ListItemAvatar>
<Avatar>{leftAvatar(data[id], id)}</Avatar>
</ListItemAvatar>
)}
<ListItemText
primary={
<div>
{primaryText(data[id], id)}
{tertiaryText && (
<span className={classes.tertiary}>
{tertiaryText(data[id], id)}
</span>
)}
</div>
}
secondary={secondaryText && secondaryText(data[id], id)}
/>
{(rightAvatar || rightIcon) && (
<ListItemSecondaryAction>
{rightAvatar && <Avatar>{rightAvatar(data[id], id)}</Avatar>}
{rightIcon && (
<ListItemIcon>{rightIcon(data[id], id)}</ListItemIcon>
)}
</ListItemSecondaryAction>
)}
</ListItem>
</LinkOrNot>
))}
</List>
)
)
}
SimpleList.propTypes = {
basePath: PropTypes.string,
className: PropTypes.string,
classes: PropTypes.object,
data: PropTypes.object,
hasBulkActions: PropTypes.bool.isRequired,
ids: PropTypes.array,
leftAvatar: PropTypes.func,
leftIcon: PropTypes.func,
linkType: PropTypes.oneOfType([
PropTypes.string,
PropTypes.bool,
PropTypes.func
]).isRequired,
onToggleItem: PropTypes.func,
primaryText: PropTypes.func,
rightAvatar: PropTypes.func,
rightIcon: PropTypes.func,
secondaryText: PropTypes.func,
selectedIds: PropTypes.arrayOf(PropTypes.any).isRequired,
tertiaryText: PropTypes.func
}
SimpleList.defaultProps = {
linkType: 'edit',
hasBulkActions: false,
selectedIds: []
}
export default SimpleList

View File

@ -3,5 +3,13 @@ import DurationField from './DurationField'
import BitrateField from './BitrateField'
import Pagination from './Pagination'
import PlayButton from './PlayButton'
import SimpleList from './SimpleList'
export { Title, DurationField, BitrateField, Pagination, PlayButton }
export {
Title,
DurationField,
BitrateField,
Pagination,
PlayButton,
SimpleList
}

View File

@ -10,13 +10,12 @@ import {
Show,
SimpleShowLayout,
TextField,
TextInput,
SimpleList
TextInput
} from 'react-admin'
import { useMediaQuery } from '@material-ui/core'
import { BitrateField, DurationField, Pagination, Title } from '../common'
import AddToQueueButton from './AddToQueueButton'
import { PlayButton } from '../common'
import { PlayButton, SimpleList } from '../common'
import { useDispatch } from 'react-redux'
import { setTrack, addTrack } from '../player'
import AddIcon from '@material-ui/icons/Add'
@ -82,7 +81,7 @@ const SongList = (props) => {
tertiaryText={(record) => (
<DurationField record={record} source={'duration'} />
)}
linkType={false}
linkType={(id, basePath, record) => dispatch(setTrack(record))}
/>
) : (
<Datagrid