diff --git a/ui/src/album/AlbumActions.jsx b/ui/src/album/AlbumActions.jsx index 96cfab09a..507b43a7e 100644 --- a/ui/src/album/AlbumActions.jsx +++ b/ui/src/album/AlbumActions.jsx @@ -5,6 +5,8 @@ import { Button, sanitizeListRestProps, TopToolbar, + useDataProvider, + useNotify, useRecordContext, useTranslate, } from 'react-admin' @@ -52,30 +54,74 @@ const AlbumActions = ({ }) => { const dispatch = useDispatch() const translate = useTranslate() + const dataProvider = useDataProvider() + const notify = useNotify() const classes = useStyles() const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('md')) const isNotSmall = useMediaQuery((theme) => theme.breakpoints.up('sm')) + const getAllSongsAndDispatch = React.useCallback( + (action) => { + if (ids?.length === record.songCount) { + return dispatch(action(data, ids)) + } + dataProvider + .getList('song', { + pagination: { page: 1, perPage: 0 }, + sort: { field: 'album', order: 'ASC' }, + filter: { album_id: record.id }, + }) + .then((res) => { + const allData = res.data.reduce( + (acc, curr) => ({ ...acc, [curr.id]: curr }), + {}, + ) + dispatch(action(allData)) + }) + .catch(() => { + notify('ra.page.error', 'warning') + }) + }, + [dataProvider, dispatch, record, data, ids, notify], + ) + const handlePlay = React.useCallback(() => { - dispatch(playTracks(data, ids)) - }, [dispatch, data, ids]) + getAllSongsAndDispatch(playTracks) + }, [getAllSongsAndDispatch]) const handlePlayNext = React.useCallback(() => { - dispatch(playNext(data, ids)) - }, [dispatch, data, ids]) + getAllSongsAndDispatch(playNext) + }, [getAllSongsAndDispatch]) const handlePlayLater = React.useCallback(() => { - dispatch(addTracks(data, ids)) - }, [dispatch, data, ids]) + getAllSongsAndDispatch(addTracks) + }, [getAllSongsAndDispatch]) const handleShuffle = React.useCallback(() => { - dispatch(shuffleTracks(data, ids)) - }, [dispatch, data, ids]) + getAllSongsAndDispatch(shuffleTracks) + }, [getAllSongsAndDispatch]) const handleAddToPlaylist = React.useCallback(() => { - const selectedIds = ids.filter((id) => !data[id].missing) - dispatch(openAddToPlaylist({ selectedIds })) - }, [dispatch, data, ids]) + if (ids?.length === record.songCount) { + const selectedIds = ids.filter((id) => !data[id].missing) + return dispatch(openAddToPlaylist({ selectedIds })) + } + dataProvider + .getList('song', { + pagination: { page: 1, perPage: 0 }, + sort: { field: 'album', order: 'ASC' }, + filter: { album_id: record.id }, + }) + .then((res) => { + const selectedIds = res.data + .filter((s) => !s.missing) + .map((s) => s.id) + dispatch(openAddToPlaylist({ selectedIds })) + }) + .catch(() => { + notify('ra.page.error', 'warning') + }) + }, [dataProvider, dispatch, record, data, ids, notify]) const handleShare = React.useCallback(() => { dispatch(openShareMenu([record.id], 'album', record.name)) diff --git a/ui/src/album/AlbumShow.jsx b/ui/src/album/AlbumShow.jsx index c9e944999..68dee861c 100644 --- a/ui/src/album/AlbumShow.jsx +++ b/ui/src/album/AlbumShow.jsx @@ -4,6 +4,7 @@ import { ShowContextProvider, useShowContext, useShowController, + Pagination, Title as RaTitle, } from 'react-admin' import { makeStyles } from '@material-ui/core/styles' @@ -40,8 +41,7 @@ const AlbumShowLayout = (props) => { reference="song" target="album_id" sort={{ field: 'album', order: 'ASC' }} - perPage={0} - pagination={null} + perPage={50} > { actions={ } + pagination={} /> )} diff --git a/ui/src/album/AlbumSongs.jsx b/ui/src/album/AlbumSongs.jsx index 8a7fd2ae4..4c942035a 100644 --- a/ui/src/album/AlbumSongs.jsx +++ b/ui/src/album/AlbumSongs.jsx @@ -89,6 +89,7 @@ const useStyles = makeStyles( const AlbumSongs = (props) => { const { data, ids } = props + const listContext = useListContext(props) const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('md')) const classes = useStyles({ isDesktop }) const dispatch = useDispatch() @@ -210,6 +211,8 @@ const AlbumSongs = (props) => { } /> + {props.pagination && + React.cloneElement(props.pagination, listContext)} ) } @@ -217,7 +220,17 @@ const AlbumSongs = (props) => { const SanitizedAlbumSongs = (props) => { removeAlbumCommentsFromSongs(props) const { loaded, loading, total, ...rest } = useListContext(props) - return <>{loaded && } + return ( + <> + {loaded && ( + + )} + + ) } export default SanitizedAlbumSongs