mirror of
https://github.com/navidrome/navidrome.git
synced 2025-06-08 19:32:16 +03:00
feat: custom SimpleList, to allow onClick handle
This commit is contained in:
parent
f0e7f3ef25
commit
a50735a94c
@ -1,10 +1,12 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { SimpleList, useGetList } from 'react-admin'
|
import { useGetList } from 'react-admin'
|
||||||
import { DurationField, PlayButton } from '../common'
|
import { DurationField, PlayButton, SimpleList } from '../common'
|
||||||
import { addTrack } from '../player'
|
import { addTrack, setTrack } from '../player'
|
||||||
import AddIcon from '@material-ui/icons/Add'
|
import AddIcon from '@material-ui/icons/Add'
|
||||||
|
import { useDispatch } from 'react-redux'
|
||||||
|
|
||||||
const AlbumSongList = (props) => {
|
const AlbumSongList = (props) => {
|
||||||
|
const dispatch = useDispatch()
|
||||||
const { record } = props
|
const { record } = props
|
||||||
const { data, total, loading, error } = useGetList(
|
const { data, total, loading, error } = useGetList(
|
||||||
'song',
|
'song',
|
||||||
@ -39,7 +41,7 @@ const AlbumSongList = (props) => {
|
|||||||
r.albumArtist && r.artist !== r.albumArtist ? r.artist : ''
|
r.albumArtist && r.artist !== r.albumArtist ? r.artist : ''
|
||||||
}
|
}
|
||||||
tertiaryText={(r) => <DurationField record={r} source={'duration'} />}
|
tertiaryText={(r) => <DurationField record={r} source={'duration'} />}
|
||||||
linkType={false}
|
linkType={(id, basePath, record) => dispatch(setTrack(record))}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,10 @@ const PlayButton = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<IconButton
|
<IconButton
|
||||||
onClick={() => dispatch(action(record))}
|
onClick={(e) => {
|
||||||
|
e.stopPropagation()
|
||||||
|
dispatch(action(record))
|
||||||
|
}}
|
||||||
{...rest}
|
{...rest}
|
||||||
size={'small'}
|
size={'small'}
|
||||||
>
|
>
|
||||||
|
149
ui/src/common/SimpleList.js
Normal file
149
ui/src/common/SimpleList.js
Normal 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
|
@ -3,5 +3,13 @@ import DurationField from './DurationField'
|
|||||||
import BitrateField from './BitrateField'
|
import BitrateField from './BitrateField'
|
||||||
import Pagination from './Pagination'
|
import Pagination from './Pagination'
|
||||||
import PlayButton from './PlayButton'
|
import PlayButton from './PlayButton'
|
||||||
|
import SimpleList from './SimpleList'
|
||||||
|
|
||||||
export { Title, DurationField, BitrateField, Pagination, PlayButton }
|
export {
|
||||||
|
Title,
|
||||||
|
DurationField,
|
||||||
|
BitrateField,
|
||||||
|
Pagination,
|
||||||
|
PlayButton,
|
||||||
|
SimpleList
|
||||||
|
}
|
||||||
|
@ -10,13 +10,12 @@ import {
|
|||||||
Show,
|
Show,
|
||||||
SimpleShowLayout,
|
SimpleShowLayout,
|
||||||
TextField,
|
TextField,
|
||||||
TextInput,
|
TextInput
|
||||||
SimpleList
|
|
||||||
} from 'react-admin'
|
} from 'react-admin'
|
||||||
import { useMediaQuery } from '@material-ui/core'
|
import { useMediaQuery } from '@material-ui/core'
|
||||||
import { BitrateField, DurationField, Pagination, Title } from '../common'
|
import { BitrateField, DurationField, Pagination, Title } from '../common'
|
||||||
import AddToQueueButton from './AddToQueueButton'
|
import AddToQueueButton from './AddToQueueButton'
|
||||||
import { PlayButton } from '../common'
|
import { PlayButton, SimpleList } from '../common'
|
||||||
import { useDispatch } from 'react-redux'
|
import { useDispatch } from 'react-redux'
|
||||||
import { setTrack, addTrack } from '../player'
|
import { setTrack, addTrack } from '../player'
|
||||||
import AddIcon from '@material-ui/icons/Add'
|
import AddIcon from '@material-ui/icons/Add'
|
||||||
@ -82,7 +81,7 @@ const SongList = (props) => {
|
|||||||
tertiaryText={(record) => (
|
tertiaryText={(record) => (
|
||||||
<DurationField record={record} source={'duration'} />
|
<DurationField record={record} source={'duration'} />
|
||||||
)}
|
)}
|
||||||
linkType={false}
|
linkType={(id, basePath, record) => dispatch(setTrack(record))}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<Datagrid
|
<Datagrid
|
||||||
|
Loading…
x
Reference in New Issue
Block a user