aboutsummaryrefslogtreecommitdiff
path: root/src/client/elm/LoggedIn
diff options
context:
space:
mode:
authorJoris2016-03-27 20:41:59 +0200
committerJoris2016-03-27 20:41:59 +0200
commit7c050fe2d2c3e8f190e019e1613d37b9d8ef22b9 (patch)
tree1465f7367335492cd246b67ab9a02968517d57a5 /src/client/elm/LoggedIn
parent702d60cbcdf85216a1b18416f4480afb77384e8a (diff)
downloadbudget-7c050fe2d2c3e8f190e019e1613d37b9d8ef22b9.tar.gz
budget-7c050fe2d2c3e8f190e019e1613d37b9d8ef22b9.tar.bz2
budget-7c050fe2d2c3e8f190e019e1613d37b9d8ef22b9.zip
Regroup account modules
Diffstat (limited to 'src/client/elm/LoggedIn')
-rw-r--r--src/client/elm/LoggedIn/Account/Action.elm17
-rw-r--r--src/client/elm/LoggedIn/Account/Model.elm64
-rw-r--r--src/client/elm/LoggedIn/Account/Update.elm75
-rw-r--r--src/client/elm/LoggedIn/Account/View.elm131
-rw-r--r--src/client/elm/LoggedIn/Action.elm5
-rw-r--r--src/client/elm/LoggedIn/Model.elm7
-rw-r--r--src/client/elm/LoggedIn/Update.elm7
-rw-r--r--src/client/elm/LoggedIn/View.elm5
8 files changed, 301 insertions, 10 deletions
diff --git a/src/client/elm/LoggedIn/Account/Action.elm b/src/client/elm/LoggedIn/Account/Action.elm
new file mode 100644
index 0000000..66ccfaa
--- /dev/null
+++ b/src/client/elm/LoggedIn/Account/Action.elm
@@ -0,0 +1,17 @@
+module LoggedIn.Account.Action
+ ( Action(..)
+ ) where
+
+import Time exposing (Time)
+
+import Model.User exposing (UserId)
+import Model.Income exposing (IncomeId)
+
+type Action =
+ NoOp
+ | ToggleDetail
+ | ToggleIncomeEdition
+ | UpdateIncomeEdition String
+ | UpdateEditionError String
+ | UpdateIncome Time Int
+ | ValidateUpdateIncome IncomeId Time Int
diff --git a/src/client/elm/LoggedIn/Account/Model.elm b/src/client/elm/LoggedIn/Account/Model.elm
new file mode 100644
index 0000000..2d0c4a3
--- /dev/null
+++ b/src/client/elm/LoggedIn/Account/Model.elm
@@ -0,0 +1,64 @@
+module LoggedIn.Account.Model
+ ( Model
+ , IncomeEdition
+ , init
+ , initIncomeEdition
+ , getCurrentIncome
+ , validateIncome
+ ) where
+
+import Result as Result exposing (Result(..))
+import Dict
+import String
+
+import Utils.Dict exposing (mapValues)
+
+import Model.Translations exposing (..)
+import Model.Income exposing (..)
+import Model.User exposing (UserId)
+
+type alias Model =
+ { me : UserId
+ , incomes : Incomes
+ , visibleDetail : Bool
+ , incomeEdition : Maybe IncomeEdition
+ }
+
+init : UserId -> Incomes -> Model
+init me incomes =
+ { me = me
+ , incomes = incomes
+ , visibleDetail = False
+ , incomeEdition = Nothing
+ }
+
+getCurrentIncome : Model -> Maybe Int
+getCurrentIncome account =
+ account.incomes
+ |> Dict.filter (\_ income -> income.userId == account.me)
+ |> Dict.values
+ |> List.sortBy .creation
+ |> List.reverse
+ |> List.head
+ |> Maybe.map .amount
+
+type alias IncomeEdition =
+ { income : String
+ , error : Maybe String
+ }
+
+initIncomeEdition : Int -> IncomeEdition
+initIncomeEdition income =
+ { income = toString income
+ , error = Nothing
+ }
+
+validateIncome : String -> Translations -> Result String Int
+validateIncome amount translations =
+ case String.toInt amount of
+ Ok number ->
+ if number > 0
+ then Ok number
+ else Err <| getMessage "IncomeMustBePositiveNumber" translations
+ Err _ ->
+ Err <| getMessage "IncomeRequired" translations
diff --git a/src/client/elm/LoggedIn/Account/Update.elm b/src/client/elm/LoggedIn/Account/Update.elm
new file mode 100644
index 0000000..a3d9745
--- /dev/null
+++ b/src/client/elm/LoggedIn/Account/Update.elm
@@ -0,0 +1,75 @@
+module LoggedIn.Account.Update
+ ( update
+ ) where
+
+import Maybe
+import Dict
+import Task
+
+import Effects exposing (Effects)
+
+import Server
+
+import LoggedIn.Account.Action as AccountAction
+import LoggedIn.Account.Model as AccountModel
+
+import Utils.Maybe exposing (isJust)
+
+update : AccountAction.Action -> AccountModel.Model -> (AccountModel.Model, Effects AccountAction.Action)
+update action account =
+ case action of
+
+ AccountAction.NoOp ->
+ (account, Effects.none)
+
+ AccountAction.ToggleDetail ->
+ ( { account | visibleDetail = not account.visibleDetail }
+ , Effects.none
+ )
+
+ AccountAction.ToggleIncomeEdition ->
+ ( { account | incomeEdition =
+ if isJust account.incomeEdition
+ then Nothing
+ else Just (AccountModel.initIncomeEdition (Maybe.withDefault 0 (AccountModel.getCurrentIncome account)))
+ }
+ , Effects.none
+ )
+
+ AccountAction.UpdateIncomeEdition income ->
+ case account.incomeEdition of
+ Just incomeEdition ->
+ ( { account | incomeEdition = Just { incomeEdition | income = income } }
+ , Effects.none
+ )
+ Nothing ->
+ ( account
+ , Effects.none
+ )
+
+ AccountAction.UpdateEditionError error ->
+ case account.incomeEdition of
+ Just incomeEdition ->
+ ( { account | incomeEdition = Just { incomeEdition | error = Just error } }
+ , Effects.none
+ )
+ Nothing ->
+ ( account
+ , Effects.none
+ )
+
+ AccountAction.UpdateIncome currentTime amount ->
+ ( account
+ , Server.setIncome currentTime amount
+ |> Task.map (\incomeId -> (AccountAction.ValidateUpdateIncome incomeId currentTime amount))
+ |> flip Task.onError (always <| Task.succeed AccountAction.NoOp)
+ |> Effects.task
+ )
+
+ AccountAction.ValidateUpdateIncome incomeId currentTime amount ->
+ ( { account
+ | incomes = Dict.insert incomeId { userId = account.me, creation = currentTime, amount = amount } account.incomes
+ , incomeEdition = Nothing
+ }
+ , Effects.none
+ )
diff --git a/src/client/elm/LoggedIn/Account/View.elm b/src/client/elm/LoggedIn/Account/View.elm
new file mode 100644
index 0000000..deee627
--- /dev/null
+++ b/src/client/elm/LoggedIn/Account/View.elm
@@ -0,0 +1,131 @@
+module LoggedIn.Account.View
+ ( view
+ ) where
+
+import List
+import Signal exposing (Address)
+
+import Html exposing (..)
+import Html as H exposing (..)
+import Html.Attributes exposing (..)
+import Html.Events exposing (..)
+
+import LoggedIn.Action as LoggedInAction
+import LoggedIn.Model as LoggedInModel
+
+import LoggedIn.Account.Action as AccountAction
+import LoggedIn.Account.Model as AccountModel
+
+import Model exposing (Model)
+import Model.User exposing (getUserName)
+import Model.Payer exposing (..)
+import Model.Translations exposing (getParamMessage, getMessage)
+import Model.Action exposing (..)
+
+import View.Expand exposing (..)
+import View.Price exposing (price)
+import View.Events exposing (onSubmitPrevDefault)
+
+import Utils.Either exposing (toMaybeError)
+
+view : Address Action -> Model -> LoggedInModel.Model -> Html
+view address model loggedInModel =
+ let account = loggedInModel.account
+ in div
+ [ classList
+ [ ("account", True)
+ , ("detail", account.visibleDetail)
+ ]
+ ]
+ [ exceedingPayers address model loggedInModel
+ , if account.visibleDetail
+ then income address model account
+ else text ""
+ ]
+
+exceedingPayers : Address Action -> Model -> LoggedInModel.Model -> Html
+exceedingPayers address model loggedInModel =
+ button
+ [ class "header"
+ , onClick address (UpdateLoggedIn << LoggedInAction.UpdateAccount <| AccountAction.ToggleDetail)
+ ]
+ ( (List.map (exceedingPayer model loggedInModel) (getOrderedExceedingPayers model.currentTime loggedInModel.users loggedInModel.account.incomes loggedInModel.payments))
+ ++ [ expand ExpandDown loggedInModel.account.visibleDetail ]
+ )
+
+exceedingPayer : Model -> LoggedInModel.Model -> ExceedingPayer -> Html
+exceedingPayer model loggedInModel payer =
+ div
+ [ class "exceedingPayer" ]
+ [ span
+ [ class "userName" ]
+ [ payer.userId
+ |> getUserName loggedInModel.users
+ |> Maybe.withDefault "−"
+ |> text
+ ]
+ , span
+ [ class "amount" ]
+ [ text ("+ " ++ (price model payer.amount)) ]
+ ]
+
+income : Address Action -> Model -> AccountModel.Model -> Html
+income address model account =
+ case account.incomeEdition of
+ Nothing ->
+ incomeRead address model account
+ Just edition ->
+ incomeEdition address model account edition
+
+incomeRead : Address Action -> Model -> AccountModel.Model -> Html
+incomeRead address model account =
+ div
+ [ class "income" ]
+ [ ( case AccountModel.getCurrentIncome account of
+ Nothing ->
+ text (getMessage "NoIncome" model.translations)
+ Just income ->
+ text (getParamMessage [price model income] "Income" model.translations)
+ )
+ , toggleIncomeEdition address "editIncomeEdition" (getMessage "Edit" model.translations)
+ ]
+
+incomeEdition : Address Action -> Model -> AccountModel.Model -> AccountModel.IncomeEdition -> Html
+incomeEdition address model account edition =
+ H.form
+ [ case AccountModel.validateIncome edition.income model.translations of
+ Ok validatedAmount ->
+ onSubmitPrevDefault address (UpdateLoggedIn << LoggedInAction.UpdateAccount <| AccountAction.UpdateIncome model.currentTime validatedAmount)
+ Err error ->
+ onSubmitPrevDefault address (UpdateLoggedIn << LoggedInAction.UpdateAccount << AccountAction.UpdateEditionError <| error)
+ , class "income"
+ ]
+ [ label
+ [ for "incomeInput" ]
+ [ text (getMessage "NewIncome" model.translations) ]
+ , input
+ [ id "incomeInput"
+ , value edition.income
+ , on "input" targetValue (Signal.message address << UpdateLoggedIn << LoggedInAction.UpdateAccount << AccountAction.UpdateIncomeEdition)
+ , maxlength 10
+ ]
+ []
+ , button
+ [ type' "submit"
+ , class "validateIncomeEdition"
+ ]
+ [ text (getMessage "Validate" model.translations) ]
+ , toggleIncomeEdition address "undoIncomeEdition" (getMessage "Undo" model.translations)
+ , case edition.error of
+ Just error -> div [ class "error" ] [ text error ]
+ Nothing -> text ""
+ ]
+
+toggleIncomeEdition : Address Action -> String -> String -> Html
+toggleIncomeEdition address className name =
+ button
+ [ type' "button"
+ , class className
+ , onClick address (UpdateLoggedIn << LoggedInAction.UpdateAccount <| AccountAction.ToggleIncomeEdition)
+ ]
+ [ text name ]
diff --git a/src/client/elm/LoggedIn/Action.elm b/src/client/elm/LoggedIn/Action.elm
index db69e2b..bd224cd 100644
--- a/src/client/elm/LoggedIn/Action.elm
+++ b/src/client/elm/LoggedIn/Action.elm
@@ -4,9 +4,10 @@ module LoggedIn.Action
import Model.Payment exposing (Payments, Payment, PaymentId, PaymentFrequency)
import Model.Action.MonthlyAction exposing (MonthlyAction)
-import Model.Action.AccountAction exposing (AccountAction)
import Model.Action.AddPaymentAction exposing (AddPaymentAction)
+import LoggedIn.Account.Action as AccountAction
+
type Action =
NoOp
| UpdateAdd AddPaymentAction
@@ -18,4 +19,4 @@ type Action =
| ToggleEdit PaymentId
| UpdatePage Int
| UpdateMonthly MonthlyAction
- | UpdateAccount AccountAction
+ | UpdateAccount AccountAction.Action
diff --git a/src/client/elm/LoggedIn/Model.elm b/src/client/elm/LoggedIn/Model.elm
index 5ab5e01..0f677c1 100644
--- a/src/client/elm/LoggedIn/Model.elm
+++ b/src/client/elm/LoggedIn/Model.elm
@@ -11,13 +11,14 @@ import Model.Init exposing (..)
import Model.View.LoggedIn.AddPayment exposing (..)
import Model.View.LoggedIn.Edition exposing (..)
import Model.View.LoggedIn.Monthly exposing (..)
-import Model.View.LoggedIn.Account exposing (..)
+
+import LoggedIn.Account.Model as AccountModel
type alias Model =
{ users : Users
, add : AddPayment
, monthly : Monthly
- , account : Account
+ , account : AccountModel.Model
, payments : Payments
, paymentsCount : Int
, paymentEdition : Maybe Edition
@@ -29,7 +30,7 @@ init initData =
{ users = initData.users
, add = initAddPayment Punctual
, monthly = initMonthly initData.monthlyPayments
- , account = initAccount initData.me initData.incomes
+ , account = AccountModel.init initData.me initData.incomes
, payments = initData.payments
, paymentsCount = initData.paymentsCount
, paymentEdition = Nothing
diff --git a/src/client/elm/LoggedIn/Update.elm b/src/client/elm/LoggedIn/Update.elm
index aac046d..e017423 100644
--- a/src/client/elm/LoggedIn/Update.elm
+++ b/src/client/elm/LoggedIn/Update.elm
@@ -16,10 +16,12 @@ import Server
import LoggedIn.Action as LoggedInAction
import LoggedIn.Model as LoggedInModel
+import LoggedIn.Account.Action as AccountAction
+import LoggedIn.Account.Update as AccountUpdate
+
import Model exposing (Model)
import Model.User exposing (UserId)
import Model.Payment exposing (..)
-import Model.Action.AccountAction as Account
import Model.Action.MonthlyAction as Monthly
import Model.Action.AddPaymentAction as AddPayment
import Model.View.LoggedIn.AddPayment exposing (..)
@@ -27,7 +29,6 @@ import Model.Translations exposing (Translations, getMessage)
import Update.LoggedIn.AddPayment exposing (updateAddPayment, addPaymentError)
import Update.LoggedIn.Monthly exposing (updateMonthly)
-import Update.LoggedIn.Account exposing (updateAccount)
update : Model -> LoggedInAction.Action -> LoggedInModel.Model -> (LoggedInModel.Model, Effects LoggedInAction.Action)
update model action loggedInView =
@@ -130,7 +131,7 @@ update model action loggedInView =
)
LoggedInAction.UpdateAccount accountAction ->
- let (newAccount, accountEffects) = updateAccount accountAction loggedInView.account
+ let (newAccount, accountEffects) = AccountUpdate.update accountAction loggedInView.account
in ( { loggedInView | account = newAccount }
, Effects.map LoggedInAction.UpdateAccount accountEffects
)
diff --git a/src/client/elm/LoggedIn/View.elm b/src/client/elm/LoggedIn/View.elm
index 8d4bdbb..8817dd2 100644
--- a/src/client/elm/LoggedIn/View.elm
+++ b/src/client/elm/LoggedIn/View.elm
@@ -9,13 +9,14 @@ import Html.Attributes exposing (..)
import LoggedIn.Model as LoggedInModel
+import LoggedIn.Account.View as AccountView
+
import Model exposing (Model)
import Model.Payment exposing (Payments)
import Model.Action exposing (Action)
import View.LoggedIn.AddPayment exposing (addPayment)
import View.LoggedIn.Monthly exposing (monthlyPayments)
-import View.LoggedIn.Account exposing (account)
import View.LoggedIn.Table exposing (paymentsTable)
import View.LoggedIn.Paging exposing (paymentsPaging)
@@ -26,7 +27,7 @@ view address model loggedInModel =
[ addPayment address model loggedInModel
, div
[ class "expandables" ]
- [ account address model loggedInModel
+ [ AccountView.view address model loggedInModel
, monthlyPayments address model loggedInModel
]
, paymentsTable address model loggedInModel