Add pagination to playlists (#969)

* add pagination

* prettier applied

* perPage_bug_fixed

* pagination_component_changed

* getAllSongs function added

* pagination component updated

* catch_error from data provider

* getAllSongsAndDispatch added

* remove ids from action function
This commit is contained in:
Ritik Pandey
2021-04-06 03:51:47 +05:30
committed by GitHub
parent cdfdf78c73
commit 69ee17402f
3 changed files with 62 additions and 25 deletions
+38 -8
View File
@@ -5,6 +5,8 @@ import {
sanitizeListRestProps, sanitizeListRestProps,
TopToolbar, TopToolbar,
useTranslate, useTranslate,
useDataProvider,
useNotify,
} from 'react-admin' } from 'react-admin'
import PlayArrowIcon from '@material-ui/icons/PlayArrow' import PlayArrowIcon from '@material-ui/icons/PlayArrow'
import ShuffleIcon from '@material-ui/icons/Shuffle' import ShuffleIcon from '@material-ui/icons/Shuffle'
@@ -23,23 +25,51 @@ import config from '../config'
const PlaylistActions = ({ className, ids, data, record, ...rest }) => { const PlaylistActions = ({ className, ids, data, record, ...rest }) => {
const dispatch = useDispatch() const dispatch = useDispatch()
const translate = useTranslate() const translate = useTranslate()
const dataProvider = useDataProvider()
const notify = useNotify()
const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('md')) const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('md'))
const getAllSongsAndDispatch = React.useCallback(
(action) => {
if (ids.length === record.songCount) {
return dispatch(action(data, ids))
}
dataProvider
.getList('playlistTrack', {
pagination: { page: 1, perPage: 0 },
sort: { field: 'id', order: 'ASC' },
filter: { playlist_id: record.id },
})
.then((res) => {
const data = res.data.reduce(
(acc, curr) => ({ ...acc, [curr.id]: curr }),
{}
)
dispatch(action(data))
})
.catch(() => {
notify('ra.page.error', 'warning')
})
},
[dataProvider, dispatch, record, data, ids, notify]
)
const handlePlay = React.useCallback(() => { const handlePlay = React.useCallback(() => {
dispatch(playTracks(data, ids)) getAllSongsAndDispatch(playTracks)
}, [dispatch, data, ids]) }, [getAllSongsAndDispatch])
const handlePlayNext = React.useCallback(() => { const handlePlayNext = React.useCallback(() => {
dispatch(playNext(data, ids)) getAllSongsAndDispatch(playNext)
}, [dispatch, data, ids]) }, [getAllSongsAndDispatch])
const handlePlayLater = React.useCallback(() => { const handlePlayLater = React.useCallback(() => {
dispatch(addTracks(data, ids)) getAllSongsAndDispatch(addTracks)
}, [dispatch, data, ids]) }, [getAllSongsAndDispatch])
const handleShuffle = React.useCallback(() => { const handleShuffle = React.useCallback(() => {
dispatch(shuffleTracks(data, ids)) getAllSongsAndDispatch(shuffleTracks)
}, [dispatch, data, ids]) }, [getAllSongsAndDispatch])
const handleDownload = React.useCallback(() => { const handleDownload = React.useCallback(() => {
subsonic.download(record.id) subsonic.download(record.id)
+3 -4
View File
@@ -4,13 +4,13 @@ import {
ShowContextProvider, ShowContextProvider,
useShowContext, useShowContext,
useShowController, useShowController,
Pagination as RaPagination,
} from 'react-admin' } from 'react-admin'
import { makeStyles } from '@material-ui/core/styles' import { makeStyles } from '@material-ui/core/styles'
import PlaylistDetails from './PlaylistDetails' import PlaylistDetails from './PlaylistDetails'
import PlaylistSongs from './PlaylistSongs' import PlaylistSongs from './PlaylistSongs'
import PlaylistActions from './PlaylistActions' import PlaylistActions from './PlaylistActions'
import { Title, isReadOnly } from '../common' import { Title, isReadOnly } from '../common'
const useStyles = makeStyles( const useStyles = makeStyles(
(theme) => ({ (theme) => ({
playlistActions: {}, playlistActions: {},
@@ -35,7 +35,7 @@ const PlaylistShowLayout = (props) => {
reference="playlistTrack" reference="playlistTrack"
target="playlist_id" target="playlist_id"
sort={{ field: 'id', order: 'ASC' }} sort={{ field: 'id', order: 'ASC' }}
perPage={0} perPage={100}
filter={{ playlist_id: props.id }} filter={{ playlist_id: props.id }}
> >
<PlaylistSongs <PlaylistSongs
@@ -50,8 +50,7 @@ const PlaylistShowLayout = (props) => {
} }
resource={'playlistTrack'} resource={'playlistTrack'}
exporter={false} exporter={false}
perPage={0} pagination={<RaPagination rowsPerPageOptions={[100, 250, 500]} />}
pagination={null}
/> />
</ReferenceManyField> </ReferenceManyField>
)} )}
+21 -13
View File
@@ -8,6 +8,7 @@ import {
useNotify, useNotify,
useVersion, useVersion,
useListContext, useListContext,
ListBase,
} from 'react-admin' } from 'react-admin'
import clsx from 'clsx' import clsx from 'clsx'
import { useDispatch } from 'react-redux' import { useDispatch } from 'react-redux'
@@ -76,8 +77,9 @@ const ReorderableList = ({ readOnly, children, ...rest }) => {
return <ReactDragListView {...rest}>{children}</ReactDragListView> return <ReactDragListView {...rest}>{children}</ReactDragListView>
} }
const PlaylistSongs = ({ playlistId, readOnly, ...props }) => { const PlaylistSongs = ({ playlistId, readOnly, actions, ...props }) => {
const { data, ids, onUnselectItems } = props const listContext = useListContext()
const { data, ids, onUnselectItems } = listContext
const isXsmall = useMediaQuery((theme) => theme.breakpoints.down('xs')) const isXsmall = useMediaQuery((theme) => theme.breakpoints.down('xs'))
const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('md')) const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('md'))
const classes = useStyles({ isDesktop }) const classes = useStyles({ isDesktop })
@@ -128,17 +130,17 @@ const PlaylistSongs = ({ playlistId, readOnly, ...props }) => {
<ListToolbar <ListToolbar
classes={{ toolbar: classes.toolbar }} classes={{ toolbar: classes.toolbar }}
filters={props.filters} filters={props.filters}
actions={props.actions} actions={actions}
{...props} {...listContext}
/> />
<div className={classes.main}> <div className={classes.main}>
<Card <Card
className={clsx(classes.content, { className={clsx(classes.content, {
[classes.bulkActionsDisplayed]: props.selectedIds.length > 0, [classes.bulkActionsDisplayed]: listContext.selectedIds.length > 0,
})} })}
key={version} key={version}
> >
<BulkActionsToolbar {...props}> <BulkActionsToolbar {...listContext}>
<PlaylistSongBulkActions <PlaylistSongBulkActions
playlistId={playlistId} playlistId={playlistId}
onUnselectItems={onUnselectItems} onUnselectItems={onUnselectItems}
@@ -152,7 +154,7 @@ const PlaylistSongs = ({ playlistId, readOnly, ...props }) => {
<SongDatagrid <SongDatagrid
expand={!isXsmall && <SongDetails />} expand={!isXsmall && <SongDetails />}
rowClick={(id) => dispatch(playTracks(data, ids, id))} rowClick={(id) => dispatch(playTracks(data, ids, id))}
{...props} {...listContext}
hasBulkActions={true} hasBulkActions={true}
contextAlwaysVisible={!isDesktop} contextAlwaysVisible={!isDesktop}
classes={{ row: classes.row }} classes={{ row: classes.row }}
@@ -172,20 +174,26 @@ const PlaylistSongs = ({ playlistId, readOnly, ...props }) => {
</Card> </Card>
</div> </div>
<AddToPlaylistDialog /> <AddToPlaylistDialog />
{React.cloneElement(props.pagination, listContext)}
</> </>
) )
} }
const SanitizedPlaylistSongs = (props) => { const SanitizedPlaylistSongs = (props) => {
const { loaded, loading, total, ...rest } = useListContext(props) const { loaded, ...rest } = props
return ( return (
<> <>
{loaded && ( {loaded && (
<PlaylistSongs <>
{...rest} <ListBase {...props}>
playlistId={props.id} <PlaylistSongs
actions={props.actions} playlistId={props.id}
/> actions={props.actions}
pagination={props.pagination}
{...rest}
/>
</ListBase>
</>
)} )}
</> </>
) )