Reducer.hs 1.62 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
module View.Income.Reducer
  ( perPage
  , reducer
  , In(..)
  ) where

import           Data.Text    (Text)
import qualified Data.Text    as T
import           Reflex.Dom   (Dynamic, Event, MonadWidget)
import qualified Reflex.Dom   as R

import           Common.Model (IncomesAndCount)

import           Loadable     (Loadable (..))
import qualified Loadable     as Loadable
import qualified Util.Ajax    as AjaxUtil

perPage :: Int
perPage = 7

data In t a b c = In
  { _in_newPage      :: Event t Int
  , _in_currentPage  :: Dynamic t Int
  , _in_addIncome    :: Event t a
  , _in_editIncome   :: Event t b
  , _in_deleteIncome :: Event t c
  }

data Action
  = LoadPage Int
  | GetResult (Either Text IncomesAndCount)

reducer :: forall t m a b c. MonadWidget t m => In t a b c -> m (Dynamic t (Loadable IncomesAndCount))
reducer input = do

  postBuild <- R.getPostBuild

  let loadPage =
        R.leftmost
          [ 1 <$ postBuild
          , _in_newPage input
          , 1 <$ _in_addIncome input
          , R.tag (R.current $ _in_currentPage input) (_in_editIncome input)
          , R.tag (R.current $ _in_currentPage input) (_in_deleteIncome input)
          ]

  getResult <- AjaxUtil.get $ fmap pageUrl loadPage

  R.foldDyn
    (\action _ -> case action of
      LoadPage _                -> Loading
      GetResult (Left err)      -> Error err
      GetResult (Right incomes) -> Loaded incomes
    )
    Loading
    (R.leftmost
      [ LoadPage <$> loadPage
      , GetResult <$> getResult
      ])

  where
    pageUrl p =
      "api/v2/incomes?page="
      <> (T.pack . show $ p)
      <> "&perPage="
      <> (T.pack . show $ perPage)