aboutsummaryrefslogtreecommitdiff
path: root/client/src/View/Income/Table.hs
blob: f865fd935a5cfc9806bc7d686dd7bdd3daff411f (plain)
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
module View.Income.Table
  ( view
  , In(..)
  , Out(..)
  ) where

import qualified Data.List               as L
import qualified Data.Maybe              as Maybe
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            (CreateIncomeForm (..), Currency,
                                          EditIncomeForm (..), Income (..),
                                          User (..), UserId)
import qualified Common.Model            as CM
import qualified Common.Msg              as Msg
import qualified Common.View.Format      as Format

import qualified Component.ConfirmDialog as ConfirmDialog
import qualified Component.Table         as Table
import qualified Util.Ajax               as Ajax
import qualified Util.Either             as EitherUtil
import qualified View.Income.Form        as Form
import           View.Income.Init        (Init (..))

data In t = In
  { _in_currentUser :: UserId
  , _in_init        :: Init
  , _in_currency    :: Currency
  , _in_incomes     :: Dynamic t [Income]
  }

data Out t = Out
  { _out_add    :: Event t Income
  , _out_edit   :: Event t Income
  , _out_delete :: Event t Income
  }

view :: forall t m. MonadWidget t m => In t -> m (Out t)
view input = do

  table <- Table.view $ Table.In
    { Table._in_headerLabel = headerLabel
    , Table._in_rows = R.ffor (_in_incomes input) $ reverse . L.sortOn _income_date
    , Table._in_cell = cell (_in_init input) (_in_currency input)
    , Table._in_perPage = 7
    , Table._in_resetPage = R.never
    , Table._in_cloneModal = \income ->
      Form.view $ Form.In
        { Form._in_operation = Form.Clone CreateIncomeForm income
        }
    , Table._in_editModal = \income ->
      Form.view $ Form.In
        { Form._in_operation = Form.Edit (EditIncomeForm $ _income_id income) income
        }
    , Table._in_deleteModal = \income ->
      ConfirmDialog.view $ ConfirmDialog.In
        { ConfirmDialog._in_header  = Msg.get Msg.Income_DeleteConfirm
        , ConfirmDialog._in_confirm = \e -> do
          res <- Ajax.delete
            (R.constDyn $ T.concat ["/api/income/", T.pack . show $ _income_id income])
            e
          return $ income <$ R.fmapMaybe EitherUtil.eitherToMaybe res
        }
    , Table._in_isOwner = (== (_in_currentUser input)) . _income_userId
    }

  return $ Out
    { _out_add = Table._out_add table
    , _out_edit = Table._out_edit table
    , _out_delete = Table._out_delete table
    }

data Header
  = UserHeader
  | AmountHeader
  | DateHeader
  deriving (Eq, Show, Bounded, Enum)

headerLabel :: Header -> Text
headerLabel UserHeader   = Msg.get Msg.Income_Name
headerLabel DateHeader   = Msg.get Msg.Income_Date
headerLabel AmountHeader = Msg.get Msg.Income_Amount

cell :: Init -> Currency -> Header -> Income -> Text
cell init currency header income =
  case header of
    UserHeader ->
      Maybe.fromMaybe "" . fmap _user_name $ CM.findUser (_income_userId income) (_init_users init)

    DateHeader ->
      Format.longDay . _income_date $ income

    AmountHeader ->
      Format.price currency . _income_amount $ income