mirror of
https://github.com/byteverse/colonnade.git
synced 2026-03-02 15:04:38 +01:00
a few more tweaks, redo Pagination data type
This commit is contained in:
parent
24a2c1d142
commit
7e002f9d5b
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"url": "https://github.com/reflex-frp/reflex-platform",
|
"url": "https://github.com/reflex-frp/reflex-platform",
|
||||||
"rev": "a16213b82f05808ad96b81939850a32ecedd18eb",
|
"rev": "1670c5b899658babeda58329d3df6b943cf6aeca",
|
||||||
"date": "2017-05-05T11:40:26-04:00",
|
"date": "2017-05-05T11:40:26-04:00",
|
||||||
"sha256": "0dfm8pcpk2zpkfrc9gxh79pkk4ac8ljfm5nqv0sksd64qlhhpj4f",
|
"sha256": "0ry3fcxiqr43c5fghsiqn0iarj4gfvk77jkc4na7j7r3k8vjdjh2",
|
||||||
"fetchSubmodules": true
|
"fetchSubmodules": true
|
||||||
}
|
}
|
||||||
|
|||||||
@ -47,6 +47,8 @@ module Reflex.Dom.Colonnade
|
|||||||
, headedResizable
|
, headedResizable
|
||||||
-- * Other Stuff
|
-- * Other Stuff
|
||||||
, defBureau
|
, defBureau
|
||||||
|
-- * Pagination
|
||||||
|
, semUiFixedPagination
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Data.String (IsString(..))
|
import Data.String (IsString(..))
|
||||||
@ -68,6 +70,7 @@ import Colonnade (Colonnade,Headed,Headless,Fascia,Cornice,Headedness(..))
|
|||||||
import Data.Monoid (Sum(..))
|
import Data.Monoid (Sum(..))
|
||||||
import Data.Proxy
|
import Data.Proxy
|
||||||
import Control.Monad.Fix (MonadFix)
|
import Control.Monad.Fix (MonadFix)
|
||||||
|
import Control.Monad (forM)
|
||||||
import qualified Colonnade as C
|
import qualified Colonnade as C
|
||||||
import qualified Colonnade.Encode as E
|
import qualified Colonnade.Encode as E
|
||||||
|
|
||||||
@ -94,6 +97,20 @@ data Bureau t h a = Bureau
|
|||||||
}
|
}
|
||||||
-- , bureauHeadRow :: h (Dynamic t (Map Text Text))
|
-- , bureauHeadRow :: h (Dynamic t (Map Text Text))
|
||||||
|
|
||||||
|
data Pagination t m = Pagination
|
||||||
|
{ paginationRows :: Int
|
||||||
|
-- ^ Maximum number of rows on a page
|
||||||
|
, paginationArrangement :: Arrangement t
|
||||||
|
-- ^ Where pagination is situated relative to table
|
||||||
|
, paginationContent :: Dynamic t Int -> m (Dynamic t Int)
|
||||||
|
-- ^ The argument to this function is an @Dynamic@ that carries
|
||||||
|
-- the total number of pages that should be available. When
|
||||||
|
-- this dynamic changes, it means that the rows backing the
|
||||||
|
-- table have been changed. Typically, this should cause
|
||||||
|
-- the @Dynamic@ in the return value to reset to 0. This
|
||||||
|
-- returned @Dynamic@ represents the current page.
|
||||||
|
}
|
||||||
|
|
||||||
-- | Where the pagination goes relative to the table
|
-- | Where the pagination goes relative to the table
|
||||||
data Arrangement t
|
data Arrangement t
|
||||||
= ArrangementAbove
|
= ArrangementAbove
|
||||||
@ -104,14 +121,6 @@ data Arrangement t
|
|||||||
(Dynamic t (Map Text Text))
|
(Dynamic t (Map Text Text))
|
||||||
-- ^ contains attributes of @\<tfoot\>@, its inner @\<tr\>@, and its inner @\<th\>@.
|
-- ^ contains attributes of @\<tfoot\>@, its inner @\<tr\>@, and its inner @\<th\>@.
|
||||||
|
|
||||||
-- | The argument to this function is an @Dynamic@ that carries
|
|
||||||
-- the total number of pages that should be available. When
|
|
||||||
-- this dynamic changes, it means that the rows backing the
|
|
||||||
-- table have been changed. Typically, this should cause
|
|
||||||
-- the @Dynamic@ in the return value to reset to 0. This
|
|
||||||
-- returned @Dynamic@ represents the current page.
|
|
||||||
newtype Pagination t m = Pagination { runPagination :: Dynamic t Int -> m (Dynamic t Int) }
|
|
||||||
|
|
||||||
class (PostBuild t m, DomBuilder t m) => Cellular t m c | c -> m, c -> t where
|
class (PostBuild t m, DomBuilder t m) => Cellular t m c | c -> m, c -> t where
|
||||||
cellularAttrs :: c b -> Dynamic t (Map Text Text)
|
cellularAttrs :: c b -> Dynamic t (Map Text Text)
|
||||||
cellularContents :: c b -> m b
|
cellularContents :: c b -> m b
|
||||||
@ -563,18 +572,15 @@ data Visible a = Visible !Bool a
|
|||||||
|
|
||||||
paginated :: forall t b h m a c.
|
paginated :: forall t b h m a c.
|
||||||
(Sizable t b h, Cellular t m c, Headedness b, MonadFix m, Functor h)
|
(Sizable t b h, Cellular t m c, Headedness b, MonadFix m, Functor h)
|
||||||
=> Bureau t b a
|
=> Bureau t b a -- ^ table class settings
|
||||||
-> Arrangement t
|
-> Pagination t m -- ^ pagination settings
|
||||||
-> Pagination t m
|
|
||||||
-> Int -- ^ number of records on a page
|
|
||||||
-> a -- ^ An inhabitant of type @a@ only used for the cells in hidden rows.
|
-> a -- ^ An inhabitant of type @a@ only used for the cells in hidden rows.
|
||||||
-> Colonnade h (Dynamic t a) (c ())
|
-> Colonnade h (Dynamic t a) (c ()) -- ^ column blueprint
|
||||||
-> Dynamic t (Vector a)
|
-> Dynamic t (Vector a) -- ^ table row data
|
||||||
-> m ()
|
-> m ()
|
||||||
paginated (Bureau tableAttrs theadAttrs bodyAttrs trAttrs) arrange (Pagination makePagination) pageSize aDef col vecD = do
|
paginated (Bureau tableAttrs theadAttrs bodyAttrs trAttrs) (Pagination pageSize arrange makePagination) aDef col vecD = do
|
||||||
let colLifted :: Colonnade h (Dynamic t (Visible a)) (c ())
|
let colLifted :: Colonnade h (Dynamic t (Visible a)) (c ())
|
||||||
colLifted = PF.lmap (fmap (\(Visible _ a) -> a)) col
|
colLifted = PF.lmap (fmap (\(Visible _ a) -> a)) col
|
||||||
-- colLifted = E.Colonnade (V.map (\(E.OneColonnade h f) -> E.OneColonnade h (\x -> maybe nothingContents f)) (E.getColonnade col))
|
|
||||||
makeVals :: Dynamic t Int -> Vector (Dynamic t (Visible a))
|
makeVals :: Dynamic t Int -> Vector (Dynamic t (Visible a))
|
||||||
makeVals page = V.generate pageSize $ \ix -> do
|
makeVals page = V.generate pageSize $ \ix -> do
|
||||||
p <- page
|
p <- page
|
||||||
@ -587,14 +593,20 @@ paginated (Bureau tableAttrs theadAttrs bodyAttrs trAttrs) arrange (Pagination m
|
|||||||
Visible isVisible a <- d
|
Visible isVisible a <- d
|
||||||
attrs <- trAttrs a
|
attrs <- trAttrs a
|
||||||
return (if isVisible then attrs else M.insertWith T.append "style" "display:none;" attrs)
|
return (if isVisible then attrs else M.insertWith T.append "style" "display:none;" attrs)
|
||||||
|
size :: Dynamic t Int
|
||||||
|
size = coerceDynamic (foldMap (\x -> coerceDynamic (sizableSize (E.oneColonnadeHead x)) :: Dynamic t (Sum Int)) (E.getColonnade col))
|
||||||
elDynAttr "table" tableAttrs $ case arrange of
|
elDynAttr "table" tableAttrs $ case arrange of
|
||||||
ArrangementFooter tfootAttrs tfootTrAttrs tfootThAttrs -> mdo
|
ArrangementFooter tfootAttrs tfootTrAttrs tfootThAttrs -> mdo
|
||||||
|
let tfootAttrsExtra = zipDynWith
|
||||||
|
( \sz attrs -> if sz > 0 then attrs else M.insert "style" "display:none;" attrs
|
||||||
|
) size tfootAttrs
|
||||||
tableHeader theadAttrs colLifted
|
tableHeader theadAttrs colLifted
|
||||||
let vals = makeVals page
|
let vals = makeVals page
|
||||||
tableBody bodyAttrs trAttrsLifted colLifted vals
|
tableBody bodyAttrs trAttrsLifted colLifted vals
|
||||||
page <- elDynAttr "tfoot" tfootAttrs $ do
|
page <- elDynAttr "tfoot" tfootAttrsExtra $ do
|
||||||
elDynAttr "tr" tfootTrAttrs $ do
|
elDynAttr "tr" tfootTrAttrs $ do
|
||||||
elDynAttr "th" tfootThAttrs $ do
|
let attrs = zipDynWith insertSizeAttr size tfootThAttrs
|
||||||
|
elDynAttr "th" attrs $ do
|
||||||
makePagination totalPages
|
makePagination totalPages
|
||||||
return ()
|
return ()
|
||||||
_ -> error "Reflex.Dom.Colonnade: paginated: write this code"
|
_ -> error "Reflex.Dom.Colonnade: paginated: write this code"
|
||||||
@ -657,5 +669,41 @@ insertSizeAttr i m
|
|||||||
| i < 1 = M.insertWith T.append "style" "display:none;" m
|
| i < 1 = M.insertWith T.append "style" "display:none;" m
|
||||||
| otherwise = M.insert "colspan" (T.pack (show i)) m
|
| otherwise = M.insert "colspan" (T.pack (show i)) m
|
||||||
|
|
||||||
|
-- | only used internally for implementations of 'Pagination'.
|
||||||
|
data Movement = Forward | Backward | Position !Int
|
||||||
|
|
||||||
|
-- | Pagination using the classes and DOM layout that Semantic UI
|
||||||
|
-- expects. The function will typically be partially applided
|
||||||
|
-- to the first two arguments to make it suitable as a field
|
||||||
|
-- of 'Pagination'.
|
||||||
|
semUiFixedPagination :: MonadWidget t m
|
||||||
|
=> Int -- ^ Maximum allowed number of pages.
|
||||||
|
-> Text -- ^ Extra classes to be applied. Already included is @ui pagination menu@.
|
||||||
|
-> Dynamic t Int
|
||||||
|
-> m (Dynamic t Int)
|
||||||
|
semUiFixedPagination maxPageCount extraClass pageCount = do
|
||||||
|
elClass "div" (T.append "ui pagination menu " extraClass) $ mdo
|
||||||
|
(bckEl,()) <- elClass' "a" "icon item" $ do
|
||||||
|
elClass "i" "left chevron icon" (return ())
|
||||||
|
let bck = Backward <$ domEvent Click bckEl
|
||||||
|
posList <- forM (enumFromTo 0 (maxPageCount - 1)) $ \i -> do
|
||||||
|
let attrs = zipDynWith (\ct pg -> M.unionsWith (<>)
|
||||||
|
[ if i < ct then M.empty else M.singleton "style" "display:none;"
|
||||||
|
, if i == pg then M.singleton "class" " active " else M.empty
|
||||||
|
, M.singleton "class" " item "
|
||||||
|
]
|
||||||
|
) pageCount page
|
||||||
|
(pageEl, ()) <- elDynAttr' "a" attrs (text (T.pack (show i)))
|
||||||
|
return (Position i <$ domEvent Click pageEl)
|
||||||
|
(fwdEl,()) <- elClass' "a" "icon item" $ do
|
||||||
|
elClass "i" "right chevron icon" (return ())
|
||||||
|
let fwd = Forward <$ domEvent Click fwdEl
|
||||||
|
let moveEv = leftmost (fwd : bck : posList)
|
||||||
|
page <- foldDynM (\move oldPage -> case move of
|
||||||
|
Backward -> return (max 0 (oldPage - 1))
|
||||||
|
Forward -> do
|
||||||
|
nowPageCount <- sample (current pageCount)
|
||||||
|
return (min (nowPageCount - 1) (oldPage + 1))
|
||||||
|
Position updatedPage -> return updatedPage
|
||||||
|
) 0 moveEv
|
||||||
|
holdUniqDyn page
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user