{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeFamilies #-}
module Yesod.Paginator.Paginate
( paginate
, paginate'
, paginateWith
, selectPaginated
, selectPaginated'
, selectPaginatedWith
, getCurrentPage
, PaginationConfig(..)
, PageParamName(..)
, defaultPaginationConfig
)
where
import Yesod.Paginator.Prelude
import Control.Monad.Trans.Reader (ReaderT)
import Database.Persist
import Yesod.Core
import Yesod.Paginator.Pages
import Yesod.Paginator.PaginationConfig
paginate :: MonadHandler m => PerPage -> [a] -> m (Pages a)
paginate per =
paginateWith defaultPaginationConfig { paginationConfigPerPage = per }
paginateWith :: MonadHandler m => PaginationConfig -> [a] -> m (Pages a)
paginateWith config items = paginate' (paginationConfigPerPage config) items
<$> (getCurrentPageWith . paginationConfigPageParamName) config
paginate' :: PerPage -> [a] -> PageNumber -> Pages a
paginate' per items p =
toPages p per (genericLength items) $ genericTake per $ genericDrop
(pageOffset p per)
items
selectPaginated
:: ( MonadHandler m
, PersistEntity record
, PersistEntityBackend record ~ BaseBackend backend
, PersistQueryRead backend
)
=> PerPage
-> [Filter record]
-> [SelectOpt record]
-> ReaderT backend m (Pages (Entity record))
selectPaginated per = selectPaginatedWith defaultPaginationConfig
{ paginationConfigPerPage = per
}
selectPaginatedWith
:: ( MonadHandler m
, PersistEntity record
, PersistEntityBackend record ~ BaseBackend backend
, PersistQueryRead backend
)
=> PaginationConfig
-> [Filter record]
-> [SelectOpt record]
-> ReaderT backend m (Pages (Entity record))
selectPaginatedWith config filters options =
selectPaginated' (paginationConfigPerPage config) filters options
=<< lift ((getCurrentPageWith . paginationConfigPageParamName) config)
selectPaginated'
:: ( MonadIO m
, PersistEntity record
, PersistEntityBackend record ~ BaseBackend backend
, PersistQueryRead backend
)
=> PerPage
-> [Filter record]
-> [SelectOpt record]
-> PageNumber
-> ReaderT backend m (Pages (Entity record))
selectPaginated' per filters options p =
toPages p per <$> (fromIntegral <$> count filters) <*> selectList
filters
(options
<> [ OffsetBy $ fromIntegral $ pageOffset p per
, LimitTo $ fromIntegral per
]
)
getCurrentPage :: MonadHandler m => m PageNumber
getCurrentPage =
getCurrentPageWith (paginationConfigPageParamName defaultPaginationConfig)
getCurrentPageWith :: MonadHandler m => PageParamName -> m PageNumber
getCurrentPageWith pageParamName = fromMaybe 1 . go <$> lookupGetParam
(unPageParamName pageParamName)
where
go :: Maybe Text -> Maybe PageNumber
go mp = readIntegral . unpack =<< mp