diff options
author | Joris | 2017-03-26 23:16:28 +0200 |
---|---|---|
committer | Joris | 2017-03-27 00:17:41 +0200 |
commit | 902acfbdbcc1d59941399753e887479e586e2748 (patch) | |
tree | 0ad90ead3f8bdf0ea7c94462d1577c8e188df469 /src | |
parent | 8062f1c9c34e9b25d76b22bd6ba2a1a99666279b (diff) |
Improve form validation
- Trim names
- Income amount accepted from 0
- Validate colors
Diffstat (limited to 'src')
21 files changed, 64 insertions, 207 deletions
diff --git a/src/client/Dialog/AddCategory/Model.elm b/src/client/Dialog/AddCategory/Model.elm index 7496c2b..3b70482 100644 --- a/src/client/Dialog/AddCategory/Model.elm +++ b/src/client/Dialog/AddCategory/Model.elm @@ -8,14 +8,16 @@ module Dialog.AddCategory.Model exposing ) import Date exposing (Date) -import View.Date as Date +import Dict import Form exposing (Form) import Form.Field as Field exposing (Field) import Form.Validate as Validate exposing (Validation) +import Model.Category exposing (Categories, Category, CategoryId) import Model.Translations exposing (Translations) -import Model.Category exposing (Category, CategoryId) +import Validation +import View.Date as Date type alias Model = { id : Maybe CategoryId @@ -49,4 +51,4 @@ validation = Validate.map3 Model (Validate.field "id" (Validate.maybe Validate.int)) (Validate.field "name" (Validate.string |> Validate.andThen Validate.nonEmpty)) - (Validate.field "color" (Validate.string |> Validate.andThen Validate.nonEmpty)) + (Validate.field "color" Validation.color) diff --git a/src/client/Dialog/AddCategory/View.elm b/src/client/Dialog/AddCategory/View.elm index 6c02351..dc55b60 100644 --- a/src/client/Dialog/AddCategory/View.elm +++ b/src/client/Dialog/AddCategory/View.elm @@ -45,7 +45,7 @@ button loggedData initialForm title buttonContent tooltip = Just message -> Tooltip.show Msg.Tooltip message Nothing -> [] ) - ++ [ onClick (Msg.Dialog <| Dialog.OpenWithUpdate dialogConfig (DialogMsg.Init "categoryname" (DialogMsg.AddCategoryMsg <| Form.Reset initialForm))) ] + ++ [ onClick (Msg.Dialog <| Dialog.OpenWithUpdate dialogConfig (DialogMsg.Init "categoryname" (DialogMsg.AddCategoryMsg (Form.Reset initialForm)))) ] ) [ buttonContent ] @@ -65,8 +65,8 @@ submitForm addCategory = Just data -> case data.id of Just categoryId -> - Msg.Dialog <| Dialog.UpdateAndClose <| Msg.EditCategory categoryId data.name data.color + Msg.Dialog <| Dialog.UpdateAndClose <| Msg.EditCategory categoryId (String.trim data.name) data.color Nothing -> - Msg.Dialog <| Dialog.UpdateAndClose <| Msg.CreateCategory data.name data.color + Msg.Dialog <| Dialog.UpdateAndClose <| Msg.CreateCategory (String.trim data.name) data.color Nothing -> Msg.Dialog <| Dialog.Update <| DialogMsg.AddCategoryMsg <| Form.Submit diff --git a/src/client/Dialog/AddIncome/Model.elm b/src/client/Dialog/AddIncome/Model.elm index ad7b25a..5e2ccf1 100644 --- a/src/client/Dialog/AddIncome/Model.elm +++ b/src/client/Dialog/AddIncome/Model.elm @@ -49,5 +49,5 @@ validation : Validation String Model validation = Validate.map3 Model (Validate.field "id" (Validate.maybe Validate.int)) - (Validate.field "amount" (Validate.int |> Validate.andThen (Validate.minInt 1))) + (Validate.field "amount" (Validate.int |> Validate.andThen (Validate.minInt 0))) (Validate.field "date" Validation.date) diff --git a/src/client/Dialog/AddPayment/View.elm b/src/client/Dialog/AddPayment/View.elm index 078d5b7..66c9f00 100644 --- a/src/client/Dialog/AddPayment/View.elm +++ b/src/client/Dialog/AddPayment/View.elm @@ -86,10 +86,10 @@ submitForm categories paymentCategories addPayment = Just paymentId -> Msg.Dialog <| Dialog.UpdateAndClose - <| Msg.EditPayment paymentId data.name data.cost data.date data.category data.frequency + <| Msg.EditPayment paymentId (String.trim data.name) data.cost data.date data.category data.frequency Nothing -> Msg.Dialog <| Dialog.UpdateAndClose - <| Msg.CreatePayment data.name data.cost data.date data.category data.frequency + <| Msg.CreatePayment (String.trim data.name) data.cost data.date data.category data.frequency Nothing -> Msg.Dialog <| Dialog.Update <| DialogMsg.AddPaymentMsg categories paymentCategories <| Form.Submit diff --git a/src/client/LoggedIn/Category/Model.elm b/src/client/LoggedIn/Category/Model.elm deleted file mode 100644 index 7092fc4..0000000 --- a/src/client/LoggedIn/Category/Model.elm +++ /dev/null @@ -1,36 +0,0 @@ -module LoggedIn.Category.Model exposing - ( Model - , AddCategory - , init - , initForm - , validation - ) - -import Date exposing (Date) - -import Form exposing (Form) -import Form.Validate as Validate exposing (Validation) -import Validation - -type alias Model = - { addCategory : Form String AddCategory - } - -type alias AddCategory = - { amount : Int - , date : Date - } - -init : Model -init = - { addCategory = initForm - } - -initForm : Form String AddCategory -initForm = Form.initial [] validation - -validation : Validation String AddCategory -validation = - Validate.map2 AddCategory - (Validate.field "amount" (Validate.int |> Validate.andThen (Validate.minInt 1))) - (Validate.field "date" Validation.date) diff --git a/src/client/LoggedIn/Category/Msg.elm b/src/client/LoggedIn/Category/Msg.elm deleted file mode 100644 index 3184297..0000000 --- a/src/client/LoggedIn/Category/Msg.elm +++ /dev/null @@ -1,9 +0,0 @@ -module LoggedIn.Category.Msg exposing - ( Msg(..) - ) - -import Form exposing (Form) - -type Msg = - NoOp - | AddCategoryMsg Form.Msg diff --git a/src/client/LoggedIn/Category/Table/View.elm b/src/client/LoggedIn/Category/Table.elm index fa7a7b1..9405e57 100644 --- a/src/client/LoggedIn/Category/Table/View.elm +++ b/src/client/LoggedIn/Category/Table.elm @@ -1,4 +1,4 @@ -module LoggedIn.Category.Table.View exposing +module LoggedIn.Category.Table exposing ( view ) @@ -25,7 +25,6 @@ import LoggedData exposing (LoggedData) import LoggedIn.Msg as LoggedInMsg -import LoggedIn.Category.Model as Category import View.Date as Date import LoggedIn.View.Format as Format @@ -34,8 +33,8 @@ import Model.Category as Category exposing (CategoryId, Category) import Model.PaymentCategory as PaymentCategory import Model.Translations exposing (getMessage) -view : LoggedData -> Category.Model -> Html Msg -view loggedData categoryModel = +view : LoggedData -> Html Msg +view loggedData = let categories = loggedData.categories |> Dict.toList @@ -44,7 +43,7 @@ view loggedData categoryModel = [ class "table" ] [ div [ class "lines" ] - ( headerLine loggedData :: List.map (paymentLine loggedData categoryModel) categories) + ( headerLine loggedData :: List.map (paymentLine loggedData) categories) , if List.isEmpty (Dict.toList loggedData.categories) then div @@ -65,8 +64,8 @@ headerLine loggedData = , div [ class "cell" ] [] ] -paymentLine : LoggedData -> Category.Model -> (CategoryId, Category) -> Html Msg -paymentLine loggedData categoryModel (categoryId, category) = +paymentLine : LoggedData -> (CategoryId, Category) -> Html Msg +paymentLine loggedData (categoryId, category) = div [ class "row" ] [ div diff --git a/src/client/LoggedIn/Category/Update.elm b/src/client/LoggedIn/Category/Update.elm deleted file mode 100644 index 1072ef0..0000000 --- a/src/client/LoggedIn/Category/Update.elm +++ /dev/null @@ -1,24 +0,0 @@ -module LoggedIn.Category.Update exposing - ( update - ) - -import Form exposing (Form) - -import LoggedData exposing (LoggedData) - -import LoggedIn.Category.Model as Category -import LoggedIn.Category.Msg as Category - -update : LoggedData -> Category.Msg -> Category.Model -> (Category.Model, Cmd Category.Msg) -update loggedData msg model = - case msg of - - Category.NoOp -> - ( model - , Cmd.none - ) - - Category.AddCategoryMsg formMsg -> - ( { model | addCategory = Form.update Category.validation formMsg model.addCategory } - , Cmd.none - ) diff --git a/src/client/LoggedIn/Category/View.elm b/src/client/LoggedIn/Category/View.elm index 4e04fa2..bba51b7 100644 --- a/src/client/LoggedIn/Category/View.elm +++ b/src/client/LoggedIn/Category/View.elm @@ -12,13 +12,12 @@ import Msg exposing (Msg) import Dialog.AddCategory.Model as AddCategory import Dialog.AddCategory.View as AddCategory -import LoggedIn.Category.Model as Category -import LoggedIn.Category.Table.View as Table +import LoggedIn.Category.Table as Table import Model.Translations exposing (getMessage, getParamMessage) -view : LoggedData -> Category.Model -> Html Msg -view loggedData categoryModel = +view : LoggedData -> Html Msg +view loggedData = div [ class "categories" ] [ div @@ -31,5 +30,5 @@ view loggedData categoryModel = (text (getMessage loggedData.translations "AddCategory")) Nothing ] - , Table.view loggedData categoryModel + , Table.view loggedData ] diff --git a/src/client/LoggedIn/Income/Model.elm b/src/client/LoggedIn/Income/Model.elm deleted file mode 100644 index 7d852b9..0000000 --- a/src/client/LoggedIn/Income/Model.elm +++ /dev/null @@ -1,36 +0,0 @@ -module LoggedIn.Income.Model exposing - ( Model - , AddIncome - , init - , initForm - , validation - ) - -import Date exposing (Date) - -import Form exposing (Form) -import Form.Validate as Validate exposing (Validation) -import Validation - -type alias Model = - { addIncome : Form String AddIncome - } - -type alias AddIncome = - { amount : Int - , date : Date - } - -init : Model -init = - { addIncome = initForm - } - -initForm : Form String AddIncome -initForm = Form.initial [] validation - -validation : Validation String AddIncome -validation = - Validate.map2 AddIncome - (Validate.field "amount" (Validate.int |> Validate.andThen (Validate.minInt 1))) - (Validate.field "date" Validation.date) diff --git a/src/client/LoggedIn/Income/Msg.elm b/src/client/LoggedIn/Income/Msg.elm deleted file mode 100644 index 0a09dad..0000000 --- a/src/client/LoggedIn/Income/Msg.elm +++ /dev/null @@ -1,9 +0,0 @@ -module LoggedIn.Income.Msg exposing - ( Msg(..) - ) - -import Form exposing (Form) - -type Msg = - NoOp - | AddIncomeMsg Form.Msg diff --git a/src/client/LoggedIn/Income/View/Table.elm b/src/client/LoggedIn/Income/Table.elm index aa5e392..f10a552 100644 --- a/src/client/LoggedIn/Income/View/Table.elm +++ b/src/client/LoggedIn/Income/Table.elm @@ -1,4 +1,4 @@ -module LoggedIn.Income.View.Table exposing +module LoggedIn.Income.Table exposing ( view ) @@ -25,7 +25,6 @@ import LoggedData exposing (LoggedData) import LoggedIn.Msg as LoggedInMsg -import LoggedIn.Income.Model as Income import View.Date as Date import LoggedIn.View.Format as Format @@ -33,8 +32,8 @@ import Model.User exposing (getUserName) import Model.Income as Income exposing (..) import Model.Translations exposing (getMessage) -view : LoggedData -> Income.Model -> Html Msg -view loggedData incomeModel = +view : LoggedData -> Html Msg +view loggedData = let incomes = loggedData.incomes |> Dict.toList @@ -44,7 +43,7 @@ view loggedData incomeModel = [ class "table" ] [ div [ class "lines" ] - ( headerLine loggedData :: List.map (paymentLine loggedData incomeModel) incomes) + ( headerLine loggedData :: List.map (paymentLine loggedData) incomes) , if List.isEmpty (Dict.toList loggedData.incomes) then div @@ -66,8 +65,8 @@ headerLine loggedData = , div [ class "cell" ] [] ] -paymentLine : LoggedData -> Income.Model -> (IncomeId, Income) -> Html Msg -paymentLine loggedData incomeModel (incomeId, income) = +paymentLine : LoggedData -> (IncomeId, Income) -> Html Msg +paymentLine loggedData (incomeId, income) = div [ class "row" ] [ div diff --git a/src/client/LoggedIn/Income/Update.elm b/src/client/LoggedIn/Income/Update.elm deleted file mode 100644 index 0023c76..0000000 --- a/src/client/LoggedIn/Income/Update.elm +++ /dev/null @@ -1,24 +0,0 @@ -module LoggedIn.Income.Update exposing - ( update - ) - -import Form exposing (Form) - -import LoggedData exposing (LoggedData) - -import LoggedIn.Income.Model as Income -import LoggedIn.Income.Msg as Income - -update : LoggedData -> Income.Msg -> Income.Model -> (Income.Model, Cmd Income.Msg) -update loggedData msg model = - case msg of - - Income.NoOp -> - ( model - , Cmd.none - ) - - Income.AddIncomeMsg formMsg -> - ( { model | addIncome = Form.update Income.validation formMsg model.addIncome } - , Cmd.none - ) diff --git a/src/client/LoggedIn/Income/View.elm b/src/client/LoggedIn/Income/View.elm index 00a1646..85b0dc3 100644 --- a/src/client/LoggedIn/Income/View.elm +++ b/src/client/LoggedIn/Income/View.elm @@ -30,18 +30,14 @@ import Model.Translations exposing (getMessage, getParamMessage) import Model.Payer exposing (useIncomesFrom) import Model.User exposing (UserId, User) import Model.View as View -import LoggedIn.Income.Model as Income - -import LoggedIn.Msg as LoggedInMsg -import LoggedIn.Income.Msg as IncomeMsg import View.Date as Date import LoggedIn.View.Format as Format import View.Color as Color -import LoggedIn.Income.View.Table as Table +import LoggedIn.Income.Table as Table -view : LoggedData -> Income.Model -> Html Msg -view loggedData incomeModel = +view : LoggedData -> Html Msg +view loggedData = div [ class "income" ] [ div @@ -60,7 +56,7 @@ view loggedData incomeModel = Nothing ] ] - , Table.view loggedData incomeModel + , Table.view loggedData ] cumulativeIncomesView : LoggedData -> Time -> Html Msg diff --git a/src/client/LoggedIn/Model.elm b/src/client/LoggedIn/Model.elm index 6bcb0b2..6c858a6 100644 --- a/src/client/LoggedIn/Model.elm +++ b/src/client/LoggedIn/Model.elm @@ -13,13 +13,9 @@ import Model.Category exposing (Categories) import Model.PaymentCategory exposing (PaymentCategories) import LoggedIn.Home.Model as Home -import LoggedIn.Income.Model as Income -import LoggedIn.Category.Model as Categories type alias Model = { home : Home.Model - , income : Income.Model - , category : Categories.Model , users : Users , me : UserId , payments : Payments @@ -31,8 +27,6 @@ type alias Model = init : Init -> Model init initData = { home = Home.init - , income = Income.init - , category = Categories.init , users = initData.users , me = initData.me , payments = initData.payments diff --git a/src/client/LoggedIn/Msg.elm b/src/client/LoggedIn/Msg.elm index a1379a6..a128cff 100644 --- a/src/client/LoggedIn/Msg.elm +++ b/src/client/LoggedIn/Msg.elm @@ -9,14 +9,10 @@ import Model.Income exposing (IncomeId) import Model.Category exposing (CategoryId) import LoggedIn.Home.Msg as Home -import LoggedIn.Income.Msg as Income -import LoggedIn.Category.Msg as Categories type Msg = NoOp | HomeMsg Home.Msg - | IncomeMsg Income.Msg - | CategoriesMsg Categories.Msg | ValidateCreatePayment PaymentId String Int Date CategoryId Frequency | ValidateEditPayment PaymentId String Int Date CategoryId Frequency | ValidateDeletePayment PaymentId diff --git a/src/client/LoggedIn/Update.elm b/src/client/LoggedIn/Update.elm index f5ce7ea..1359e1a 100644 --- a/src/client/LoggedIn/Update.elm +++ b/src/client/LoggedIn/Update.elm @@ -28,12 +28,6 @@ import LoggedIn.Home.Msg as Home import LoggedIn.Home.Update as Home import LoggedIn.Home.Model as Home -import LoggedIn.Income.Update as Income -import LoggedIn.Income.Model as Income - -import LoggedIn.Category.Update as Categories -import LoggedIn.Category.Model as Categories - import Utils.Cmd exposing ((:>)) update : Model -> LoggedInMsg.Msg -> LoggedInModel.Model -> (LoggedInModel.Model, Cmd LoggedInMsg.Msg) @@ -53,20 +47,6 @@ update model msg loggedIn = , Cmd.map LoggedInMsg.HomeMsg effects ) - LoggedInMsg.IncomeMsg incomeMsg -> - case Income.update loggedData incomeMsg loggedIn.income of - (income, cmd) -> - ( { loggedIn | income = income } - , Cmd.map LoggedInMsg.IncomeMsg cmd - ) - - LoggedInMsg.CategoriesMsg categoriesMsg -> - case Categories.update loggedData categoriesMsg loggedIn.category of - (category, cmd) -> - ( { loggedIn | category = category } - , Cmd.map LoggedInMsg.CategoriesMsg cmd - ) - LoggedInMsg.ValidateCreatePayment paymentId name cost date category frequency -> update model (LoggedInMsg.HomeMsg <| Home.SearchMsg (Form.Reset (Home.searchInitial frequency))) loggedIn :> update model (LoggedInMsg.HomeMsg <| Home.UpdatePage 1) diff --git a/src/client/LoggedIn/View.elm b/src/client/LoggedIn/View.elm index 2e42a73..ddc85d5 100644 --- a/src/client/LoggedIn/View.elm +++ b/src/client/LoggedIn/View.elm @@ -26,8 +26,8 @@ view model loggedIn = [ let loggedData = LoggedData.build model loggedIn in case model.page of Page.Home -> Home.view loggedData loggedIn.home - Page.Income -> Income.view loggedData loggedIn.income - Page.Categories -> Categories.view loggedData loggedIn.category + Page.Income -> Income.view loggedData + Page.Categories -> Categories.view loggedData Page.Statistics -> Stat.view loggedData Page.NotFound -> div [] [ text (getMessage model.translations "PageNotFound") ] ] diff --git a/src/client/Validation.elm b/src/client/Validation.elm index 4781c3d..de27963 100644 --- a/src/client/Validation.elm +++ b/src/client/Validation.elm @@ -2,15 +2,19 @@ module Validation exposing ( cost , date , category + , color + , new ) import Date exposing (Date) import Date.Extra.Core exposing (intToMonth) import Date.Extra.Create exposing (dateFromFields) import Dict +import Regex import String exposing (toInt, split) import Form.Validate as Validate exposing (Validation) +import Form.Error as Error exposing (ErrorValue(CustomError)) import Model.Category exposing (Categories, CategoryId) @@ -45,3 +49,17 @@ category categories = Err _ -> Err (Validate.customError "InvalidCategory") ) + +color : Validation String String +color = + Validate.customValidation Validate.string (\str -> + if Regex.contains (Regex.regex "^#[0-9a-fA-F]{6}$") str + then Ok str + else Err (Validate.customError "InvalidColor") + ) + +new : List x -> x -> Validation String x +new xs x field = + if List.member x xs + then Err (Error.value <| CustomError "AlreadyExists") + else Ok x diff --git a/src/server/Model/Message/Key.hs b/src/server/Model/Message/Key.hs index 79ccf39..efe8aaa 100644 --- a/src/server/Model/Message/Key.hs +++ b/src/server/Model/Message/Key.hs @@ -130,6 +130,8 @@ data Key = | CostMustNotBeNull | InvalidInt | InvalidCategory + | InvalidColor + | AlreadyExists | SmallerIntThan | GreaterIntThan diff --git a/src/server/Model/Message/Translations.hs b/src/server/Model/Message/Translations.hs index 16fc3fd..90f509a 100644 --- a/src/server/Model/Message/Translations.hs +++ b/src/server/Model/Message/Translations.hs @@ -350,7 +350,7 @@ m l Color = m l UsedCategory = case l of English -> "This category is currently being used" - French -> "Cette catégorie est utilisée actuellement" + French -> "Cette catégorie est actuellement utilisée" -- Statistics @@ -513,6 +513,16 @@ m l InvalidCategory = English -> "Invalid category" French -> "Catégorie invalide" +m l InvalidColor = + case l of + English -> "Invalid color" + French -> "Couleur invalide" + +m l AlreadyExists = + case l of + English -> "Dupplicate field" + French -> "Doublon" + m l SmallerIntThan = case l of English -> "Integer bigger than {1} or equal required" |