packages feed

yesod-paginator 1.1.0.2 → 1.1.1.0

raw patch · 8 files changed

+210/−16 lines, 8 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Yesod.Paginator: PageParamName :: Text -> PageParamName
+ Yesod.Paginator: PaginationConfig :: PageParamName -> PerPage -> PaginationConfig
+ Yesod.Paginator: [paginationConfigPageParamName] :: PaginationConfig -> PageParamName
+ Yesod.Paginator: [paginationConfigPerPage] :: PaginationConfig -> PerPage
+ Yesod.Paginator: [unPageParamName] :: PageParamName -> Text
+ Yesod.Paginator: data PaginationConfig
+ Yesod.Paginator: ellipsedWith :: PaginationConfig -> Natural -> PaginationWidget m a
+ Yesod.Paginator: newtype PageParamName
+ Yesod.Paginator: paginateWith :: MonadHandler m => PaginationConfig -> [a] -> m (Pages a)
+ Yesod.Paginator: selectPaginatedWith :: (MonadHandler m, PersistEntity record, PersistEntityBackend record ~ BaseBackend backend, PersistQueryRead backend) => PaginationConfig -> [Filter record] -> [SelectOpt record] -> ReaderT backend m (Pages (Entity record))
+ Yesod.Paginator: simpleWith :: PaginationConfig -> Natural -> PaginationWidget m a
+ Yesod.Paginator.Paginate: PageParamName :: Text -> PageParamName
+ Yesod.Paginator.Paginate: PaginationConfig :: PageParamName -> PerPage -> PaginationConfig
+ Yesod.Paginator.Paginate: [paginationConfigPageParamName] :: PaginationConfig -> PageParamName
+ Yesod.Paginator.Paginate: [paginationConfigPerPage] :: PaginationConfig -> PerPage
+ Yesod.Paginator.Paginate: [unPageParamName] :: PageParamName -> Text
+ Yesod.Paginator.Paginate: data PaginationConfig
+ Yesod.Paginator.Paginate: defaultPaginationConfig :: PaginationConfig
+ Yesod.Paginator.Paginate: newtype PageParamName
+ Yesod.Paginator.Paginate: paginateWith :: MonadHandler m => PaginationConfig -> [a] -> m (Pages a)
+ Yesod.Paginator.Paginate: selectPaginatedWith :: (MonadHandler m, PersistEntity record, PersistEntityBackend record ~ BaseBackend backend, PersistQueryRead backend) => PaginationConfig -> [Filter record] -> [SelectOpt record] -> ReaderT backend m (Pages (Entity record))
+ Yesod.Paginator.PaginationConfig: PageParamName :: Text -> PageParamName
+ Yesod.Paginator.PaginationConfig: PaginationConfig :: PageParamName -> PerPage -> PaginationConfig
+ Yesod.Paginator.PaginationConfig: [paginationConfigPageParamName] :: PaginationConfig -> PageParamName
+ Yesod.Paginator.PaginationConfig: [paginationConfigPerPage] :: PaginationConfig -> PerPage
+ Yesod.Paginator.PaginationConfig: [unPageParamName] :: PageParamName -> Text
+ Yesod.Paginator.PaginationConfig: data PaginationConfig
+ Yesod.Paginator.PaginationConfig: defaultPaginationConfig :: PaginationConfig
+ Yesod.Paginator.PaginationConfig: instance GHC.Classes.Eq Yesod.Paginator.PaginationConfig.PageParamName
+ Yesod.Paginator.PaginationConfig: instance GHC.Read.Read Yesod.Paginator.PaginationConfig.PageParamName
+ Yesod.Paginator.PaginationConfig: instance GHC.Show.Show Yesod.Paginator.PaginationConfig.PageParamName
+ Yesod.Paginator.PaginationConfig: instance Web.PathPieces.PathPiece Yesod.Paginator.PaginationConfig.PageParamName
+ Yesod.Paginator.PaginationConfig: newtype PageParamName
+ Yesod.Paginator.Prelude: maximumBound :: Ord a => a -> [a] -> a
+ Yesod.Paginator.Prelude: maximumBoundBy :: () => a -> (a -> a -> Ordering) -> [a] -> a
+ Yesod.Paginator.Prelude: maximumBounded :: (Ord a, Bounded a) => [a] -> a
+ Yesod.Paginator.Prelude: minimumBound :: Ord a => a -> [a] -> a
+ Yesod.Paginator.Prelude: minimumBoundBy :: () => a -> (a -> a -> Ordering) -> [a] -> a
+ Yesod.Paginator.Prelude: minimumBounded :: (Ord a, Bounded a) => [a] -> a
+ Yesod.Paginator.Widgets: ellipsedWith :: PaginationConfig -> Natural -> PaginationWidget m a
+ Yesod.Paginator.Widgets: simpleWith :: PaginationConfig -> Natural -> PaginationWidget m a

Files

src/Yesod/Paginator.hs view
@@ -51,11 +51,19 @@      -- * Paginators     , paginate+    , paginateWith     , selectPaginated+    , selectPaginatedWith      -- * Widgets     , simple+    , simpleWith     , ellipsed+    , ellipsedWith++    -- * Pagination configuration+    , PaginationConfig(..)+    , PageParamName(..)     ) where 
src/Yesod/Paginator/Paginate.hs view
@@ -1,13 +1,17 @@ {-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TypeFamilies #-}  module Yesod.Paginator.Paginate     ( paginate     , paginate'+    , paginateWith     , selectPaginated     , selectPaginated'+    , selectPaginatedWith     , getCurrentPage+    , PaginationConfig(..)+    , PageParamName(..)+    , defaultPaginationConfig     ) where @@ -17,11 +21,18 @@ import Database.Persist import Yesod.Core import Yesod.Paginator.Pages+import Yesod.Paginator.PaginationConfig  -- | Paginate a list of items paginate :: MonadHandler m => PerPage -> [a] -> m (Pages a)-paginate per items = paginate' per items <$> getCurrentPage+paginate per =+    paginateWith defaultPaginationConfig { paginationConfigPerPage = per } +-- | Paginate a list of items given a pagination config+paginateWith :: MonadHandler m => PaginationConfig -> [a] -> m (Pages a)+paginateWith config items = paginate' (paginationConfigPerPage config) items+    <$> (getCurrentPageWith . paginationConfigPageParamName) config+ -- | A version where the current page is given -- -- This can be used to avoid the monadic context altogether.@@ -58,9 +69,25 @@     -> [Filter record]     -> [SelectOpt record]     -> ReaderT backend m (Pages (Entity record))-selectPaginated per filters options =-    selectPaginated' per filters options =<< lift getCurrentPage+selectPaginated per = selectPaginatedWith defaultPaginationConfig+    { paginationConfigPerPage = per+    } +-- | Paginate out of a persistent database given a pagination config+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)+ -- | A version where the current page is given -- -- This can be used to avoid the @'MonadHandler'@ context.@@ -86,7 +113,12 @@         )  getCurrentPage :: MonadHandler m => m PageNumber-getCurrentPage = fromMaybe 1 . go <$> lookupGetParam "p"+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
+ src/Yesod/Paginator/PaginationConfig.hs view
@@ -0,0 +1,30 @@+{-# LANGUAGE DerivingStrategies #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE OverloadedStrings #-}++module Yesod.Paginator.PaginationConfig+    ( PaginationConfig(..)+    , PageParamName(..)+    , defaultPaginationConfig+    )+where++import Yesod.Paginator.Prelude++import Yesod.Core+import Yesod.Paginator.Pages++newtype PageParamName = PageParamName { unPageParamName :: Text }+    deriving (Eq)+    deriving newtype (Read, Show, PathPiece)++data PaginationConfig = PaginationConfig+  { paginationConfigPageParamName :: PageParamName+  , paginationConfigPerPage :: PerPage+  }++defaultPaginationConfig :: PaginationConfig+defaultPaginationConfig = PaginationConfig+    { paginationConfigPageParamName = PageParamName "p"+    , paginationConfigPerPage = 3+    }
src/Yesod/Paginator/Prelude.hs view
@@ -12,7 +12,6 @@ import Control.Monad as X import Data.List as X import Data.Maybe as X-import Data.Semigroup as X ((<>)) import Data.Text as X (Text, pack, unpack) import Numeric.Natural as X import Safe as X
src/Yesod/Paginator/Widgets.hs view
@@ -4,7 +4,9 @@ module Yesod.Paginator.Widgets     ( PaginationWidget     , simple+    , simpleWith     , ellipsed+    , ellipsedWith     ) where @@ -14,6 +16,7 @@ import Network.URI.Encode (encodeText) import Yesod.Core import Yesod.Paginator.Pages+import Yesod.Paginator.Paginate  type PaginationWidget site a = Pages a -> WidgetFor site () @@ -46,9 +49,12 @@ -- @ -- simple :: Natural -> PaginationWidget m a-simple elements pages = do-    updateGetParams <- getUpdateGetParams+simple = simpleWith defaultPaginationConfig +simpleWith :: PaginationConfig -> Natural -> PaginationWidget m a+simpleWith config elements pages = do+    updateGetParams <- getUpdateGetParams (paginationConfigPageParamName config)+     let (prevPages, nextPages) = getBalancedPages elements pages         mPrevPage = getPreviousPage pages         mNextPage = getNextPage pages@@ -80,9 +86,12 @@  -- | Show pages before and after, ellipsis, and first/last ellipsed :: Natural -> PaginationWidget m a-ellipsed elements pages = do-    updateGetParams <- getUpdateGetParams+ellipsed = ellipsedWith defaultPaginationConfig +ellipsedWith :: PaginationConfig -> Natural -> PaginationWidget m a+ellipsedWith config elements pages = do+    updateGetParams <- getUpdateGetParams (paginationConfigPageParamName config)+     let (prevPages, nextPages) = getBalancedPages elements pages          mPrevPage = getPreviousPage pages@@ -159,10 +168,10 @@     prevPagesNaive = takePreviousPages (elements `div` 2) pages     prevPagesCalcd = takePreviousPages (elements - genericLength nextPages - 1) pages -getUpdateGetParams :: WidgetFor site (PageNumber -> [(Text, Text)])-getUpdateGetParams = do+getUpdateGetParams :: PageParamName -> WidgetFor site (PageNumber -> [(Text, Text)])+getUpdateGetParams pageParamName = do     params <- handlerToWidget $ reqGetParams <$> getRequest-    pure $ \number -> nubOn fst $ [("p", tshow number)] <> params+    pure $ \number -> nubOn fst $ [(unPageParamName pageParamName, tshow number)] <> params  renderGetParams :: [(Text, Text)] -> Text renderGetParams [] = ""
test/SpecHelper.hs view
@@ -21,6 +21,8 @@ mkYesod "App" [parseRoutes|     /simple/#ItemsCount/#PerPage/#Natural SimpleR GET     /ellipsed/#ItemsCount/#PerPage/#Natural EllipsedR GET+    /simple-param-name/#ItemsCount/#PerPage/#Natural/#PageParamName SimpleParamNameR GET+    /ellipsed-param-name/#ItemsCount/#PerPage/#Natural/#PageParamName EllipsedParamNameR GET |]  instance Yesod App@@ -34,6 +36,28 @@ getEllipsedR total per elements = do     pages <- paginate per $ genericReplicate total ()     defaultLayout [whamlet|^{ellipsed elements pages}|]++getSimpleParamNameR+    :: ItemsCount -> PerPage -> Natural -> PageParamName -> Handler Html+getSimpleParamNameR total per elements pageParamName = do+    let+        config = PaginationConfig+            { paginationConfigPerPage = per+            , paginationConfigPageParamName = pageParamName+            }+    pages <- paginateWith config $ genericReplicate total ()+    defaultLayout [whamlet|^{simpleWith config elements pages}|]++getEllipsedParamNameR+    :: ItemsCount -> PerPage -> Natural -> PageParamName -> Handler Html+getEllipsedParamNameR total per elements pageParamName = do+    let+        config = PaginationConfig+            { paginationConfigPerPage = per+            , paginationConfigPageParamName = pageParamName+            }+    pages <- paginateWith config $ genericReplicate total ()+    defaultLayout [whamlet|^{ellipsedWith config elements pages}|]  withApp :: SpecWith (TestApp App) -> Spec withApp = before $ pure (App, id)
test/Yesod/Paginator/WidgetsSpec.hs view
@@ -98,3 +98,94 @@             , "<li class=\"next disabled\"><a>»</a></li>"             , "</ul>"             ]++    describe "simple with page param" $ it "works" $ do+        get $ SimpleParamNameR 10 3 3 (PageParamName "page")++        statusIs 200+        bodyContains $ concat+            [ "<ul class=\"pagination\">"+            , "<li class=\"prev disabled\"><a>«</a></li>"+            , "<li class=\"active disabled\"><a>1</a></li>"+            , "<li class=\"next\"><a href=\"?page=2\">2</a></li>"+            , "<li class=\"next\"><a href=\"?page=3\">3</a></li>"+            , "<li class=\"next\"><a href=\"?page=2\">»</a></li>"+            , "</ul>"+            ]++        request $ do+            addGetParam "page" "3"+            setUrl $ SimpleParamNameR 10 3 3 (PageParamName "page")++        statusIs 200+        bodyContains $ concat+            [ "<ul class=\"pagination\">"+            , "<li class=\"prev\"><a href=\"?page=2\">«</a></li>"+            , "<li class=\"prev\"><a href=\"?page=2\">2</a></li>"+            , "<li class=\"active disabled\"><a>3</a></li>"+            , "<li class=\"next\"><a href=\"?page=4\">4</a></li>"+            , "<li class=\"next\"><a href=\"?page=4\">»</a></li>"+            , "</ul>"+            ]++        request $ do+            addGetParam "page" "4"+            setUrl $ SimpleParamNameR 10 3 3 (PageParamName "page")++        statusIs 200+        bodyContains $ concat+            [ "<ul class=\"pagination\">"+            , "<li class=\"prev\"><a href=\"?page=3\">«</a></li>"+            , "<li class=\"prev\"><a href=\"?page=2\">2</a></li>"+            , "<li class=\"prev\"><a href=\"?page=3\">3</a></li>"+            , "<li class=\"active disabled\"><a>4</a></li>"+            , "<li class=\"next disabled\"><a>»</a></li>"+            , "</ul>"+            ]++    describe "ellipsed with page param" $ it "works" $ do+        get $ EllipsedParamNameR 10 3 3 (PageParamName "page")++        statusIs 200+        bodyContains $ concat+            [ "<ul class=\"pagination\">"+            , "<li class=\"prev disabled\"><a>«</a></li>"+            , "<li class=\"active disabled\"><a>1</a></li>"+            , "<li class=\"next\"><a href=\"?page=2\">2</a></li>"+            , "<li class=\"next\"><a href=\"?page=3\">3</a></li>"+            , "<li class=\"next\"><a href=\"?page=4\">4</a></li>"+            , "<li class=\"next\"><a href=\"?page=2\">»</a></li>"+            , "</ul>"+            ]++        get $ EllipsedParamNameR 15 3 3 (PageParamName "page")++        statusIs 200+        bodyContains $ concat+            [ "<ul class=\"pagination\">"+            , "<li class=\"prev disabled\"><a>«</a></li>"+            , "<li class=\"active disabled\"><a>1</a></li>"+            , "<li class=\"next\"><a href=\"?page=2\">2</a></li>"+            , "<li class=\"next\"><a href=\"?page=3\">3</a></li>"+            , "<li class=\"next disabled\"><a>…</a></li>"+            , "<li class=\"next\"><a href=\"?page=5\">5</a></li>"+            , "<li class=\"next\"><a href=\"?page=2\">»</a></li>"+            , "</ul>"+            ]++        request $ do+            addGetParam "page" "5"+            setUrl $ EllipsedParamNameR 15 3 3 (PageParamName "page")++        statusIs 200+        bodyContains $ concat+            [ "<ul class=\"pagination\">"+            , "<li class=\"prev\"><a href=\"?page=4\">«</a></li>"+            , "<li class=\"prev\"><a href=\"?page=1\">1</a></li>"+            , "<li class=\"prev disabled\"><a>…</a></li>"+            , "<li class=\"prev\"><a href=\"?page=3\">3</a></li>"+            , "<li class=\"prev\"><a href=\"?page=4\">4</a></li>"+            , "<li class=\"active disabled\"><a>5</a></li>"+            , "<li class=\"next disabled\"><a>»</a></li>"+            , "</ul>"+            ]
yesod-paginator.cabal view
@@ -1,13 +1,13 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.31.1.+-- This file has been generated from package.yaml by hpack version 0.31.2. -- -- see: https://github.com/sol/hpack ----- hash: c412aee17c1ede253c8e371db6af5b8e8618b2b0a835c5410cf4b90cd566aaeb+-- hash: 997fa6b9ee2b93c5590ad92497cf2b628931167ff2ccdd566227408106b0e1df  name:           yesod-paginator-version:        1.1.0.2+version:        1.1.1.0 synopsis:       A pagination approach for yesod description:    Paginate a list showing a per-item widget and links to other pages category:       Web, Yesod@@ -32,6 +32,7 @@       Yesod.Paginator       Yesod.Paginator.Pages       Yesod.Paginator.Paginate+      Yesod.Paginator.PaginationConfig       Yesod.Paginator.Prelude       Yesod.Paginator.Widgets   other-modules: