mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-06-05 22:55:58 +00:00
Ui improvements
- don't show custom fields in edit menu if there are none. This reduces load of ui elements. The first custom field must be created in manage-data page. - Add more validation to the money type
This commit is contained in:
parent
ff30ed5558
commit
bb19e02c66
@ -13,6 +13,7 @@ import Api.Model.CustomField exposing (CustomField)
|
|||||||
import Api.Model.ItemFieldValue exposing (ItemFieldValue)
|
import Api.Model.ItemFieldValue exposing (ItemFieldValue)
|
||||||
import Comp.DatePicker
|
import Comp.DatePicker
|
||||||
import Data.CustomFieldType exposing (CustomFieldType)
|
import Data.CustomFieldType exposing (CustomFieldType)
|
||||||
|
import Data.Money
|
||||||
import Date exposing (Date)
|
import Date exposing (Date)
|
||||||
import DatePicker exposing (DatePicker)
|
import DatePicker exposing (DatePicker)
|
||||||
import Html exposing (..)
|
import Html exposing (..)
|
||||||
@ -130,14 +131,14 @@ initWith value =
|
|||||||
Data.CustomFieldType.Numeric ->
|
Data.CustomFieldType.Numeric ->
|
||||||
let
|
let
|
||||||
( fm, _ ) =
|
( fm, _ ) =
|
||||||
updateFloatModel value.value identity
|
updateFloatModel value.value string2Float
|
||||||
in
|
in
|
||||||
NumberField fm
|
NumberField fm
|
||||||
|
|
||||||
Data.CustomFieldType.Money ->
|
Data.CustomFieldType.Money ->
|
||||||
let
|
let
|
||||||
( fm, _ ) =
|
( fm, _ ) =
|
||||||
updateFloatModel value.value identity
|
updateFloatModel value.value Data.Money.fromString
|
||||||
in
|
in
|
||||||
MoneyField fm
|
MoneyField fm
|
||||||
|
|
||||||
@ -174,35 +175,32 @@ type alias UpdateResult =
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
updateFloatModel : String -> (Float -> Float) -> ( FloatModel, FieldResult )
|
updateFloatModel : String -> (String -> Result String Float) -> ( FloatModel, FieldResult )
|
||||||
updateFloatModel msg rounding =
|
updateFloatModel msg parse =
|
||||||
case String.toFloat msg of
|
case parse msg of
|
||||||
Just n ->
|
Ok n ->
|
||||||
let
|
( { input = msg
|
||||||
fieldVal =
|
, result = Ok n
|
||||||
if String.endsWith "." msg || String.endsWith ".0" msg then
|
|
||||||
msg
|
|
||||||
|
|
||||||
else
|
|
||||||
String.fromFloat (rounding n)
|
|
||||||
in
|
|
||||||
( { input = fieldVal
|
|
||||||
, result = Ok (rounding n)
|
|
||||||
}
|
}
|
||||||
, Value (String.fromFloat (rounding n))
|
, Value msg
|
||||||
)
|
)
|
||||||
|
|
||||||
Nothing ->
|
Err err ->
|
||||||
( { input = msg
|
( { input = msg
|
||||||
, result = Err ("Not a number: " ++ msg)
|
, result = Err err
|
||||||
}
|
}
|
||||||
, NoResult
|
, NoResult
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
roundScale2 : Float -> Float
|
string2Float : String -> Result String Float
|
||||||
roundScale2 input =
|
string2Float str =
|
||||||
(round (input * 100) |> toFloat) / 100
|
case String.toFloat str of
|
||||||
|
Just n ->
|
||||||
|
Ok n
|
||||||
|
|
||||||
|
Nothing ->
|
||||||
|
Err ("Not a number: " ++ str)
|
||||||
|
|
||||||
|
|
||||||
update : Msg -> Model -> UpdateResult
|
update : Msg -> Model -> UpdateResult
|
||||||
@ -218,7 +216,7 @@ update msg model =
|
|||||||
( NumberMsg str, NumberField _ ) ->
|
( NumberMsg str, NumberField _ ) ->
|
||||||
let
|
let
|
||||||
( fm, res ) =
|
( fm, res ) =
|
||||||
updateFloatModel str identity
|
updateFloatModel str string2Float
|
||||||
|
|
||||||
model_ =
|
model_ =
|
||||||
{ model | fieldModel = NumberField fm }
|
{ model | fieldModel = NumberField fm }
|
||||||
@ -228,7 +226,9 @@ update msg model =
|
|||||||
( MoneyMsg str, MoneyField _ ) ->
|
( MoneyMsg str, MoneyField _ ) ->
|
||||||
let
|
let
|
||||||
( fm, res ) =
|
( fm, res ) =
|
||||||
updateFloatModel str roundScale2
|
updateFloatModel
|
||||||
|
str
|
||||||
|
Data.Money.fromString
|
||||||
|
|
||||||
model_ =
|
model_ =
|
||||||
{ model | fieldModel = MoneyField fm }
|
{ model | fieldModel = MoneyField fm }
|
||||||
|
@ -7,6 +7,7 @@ module Comp.CustomFieldMultiInput exposing
|
|||||||
, init
|
, init
|
||||||
, initCmd
|
, initCmd
|
||||||
, initWith
|
, initWith
|
||||||
|
, nonEmpty
|
||||||
, setValues
|
, setValues
|
||||||
, update
|
, update
|
||||||
, view
|
, view
|
||||||
@ -59,6 +60,11 @@ type alias FieldSelect =
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
nonEmpty : Model -> Bool
|
||||||
|
nonEmpty model =
|
||||||
|
not (List.isEmpty model.availableFields && List.isEmpty model.visibleFields)
|
||||||
|
|
||||||
|
|
||||||
initWith : List CustomField -> Model
|
initWith : List CustomField -> Model
|
||||||
initWith fields =
|
initWith fields =
|
||||||
{ fieldModels = Dict.empty
|
{ fieldModels = Dict.empty
|
||||||
|
@ -729,6 +729,10 @@ renderEditForm settings model =
|
|||||||
else
|
else
|
||||||
span [ class "invisible hidden" ] []
|
span [ class "invisible hidden" ] []
|
||||||
|
|
||||||
|
showCustomFields =
|
||||||
|
fieldVisible Data.Fields.CustomFields
|
||||||
|
&& Comp.CustomFieldMultiInput.nonEmpty model.customFieldsModel
|
||||||
|
|
||||||
customFieldSettings =
|
customFieldSettings =
|
||||||
Comp.CustomFieldMultiInput.ViewSettings True "field"
|
Comp.CustomFieldMultiInput.ViewSettings True "field"
|
||||||
in
|
in
|
||||||
@ -777,14 +781,20 @@ item visible. This message will disappear then.
|
|||||||
"""
|
"""
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, optional [ Data.Fields.CustomFields ] <|
|
, if showCustomFields then
|
||||||
h4 [ class "ui dividing header" ]
|
h4 [ class "ui dividing header" ]
|
||||||
[ Icons.customFieldIcon ""
|
[ Icons.customFieldIcon ""
|
||||||
, text "Custom Fields"
|
, text "Custom Fields"
|
||||||
]
|
]
|
||||||
, optional [ Data.Fields.CustomFields ] <|
|
|
||||||
|
else
|
||||||
|
span [ class "hidden invisible" ] []
|
||||||
|
, if showCustomFields then
|
||||||
Html.map CustomFieldMsg
|
Html.map CustomFieldMsg
|
||||||
(Comp.CustomFieldMultiInput.view customFieldSettings model.customFieldsModel)
|
(Comp.CustomFieldMultiInput.view customFieldSettings model.customFieldsModel)
|
||||||
|
|
||||||
|
else
|
||||||
|
span [ class "hidden invisible" ] []
|
||||||
, optional [ Data.Fields.DueDate, Data.Fields.Date ] <|
|
, optional [ Data.Fields.DueDate, Data.Fields.Date ] <|
|
||||||
h4 [ class "ui dividing header" ]
|
h4 [ class "ui dividing header" ]
|
||||||
[ Icons.itemDatesIcon ""
|
[ Icons.itemDatesIcon ""
|
||||||
|
43
modules/webapp/src/main/elm/Data/Money.elm
Normal file
43
modules/webapp/src/main/elm/Data/Money.elm
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
module Data.Money exposing
|
||||||
|
( Money
|
||||||
|
, format
|
||||||
|
, fromString
|
||||||
|
, roundMoney
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
type alias Money =
|
||||||
|
Float
|
||||||
|
|
||||||
|
|
||||||
|
fromString : String -> Result String Money
|
||||||
|
fromString str =
|
||||||
|
let
|
||||||
|
points =
|
||||||
|
String.indexes "." str
|
||||||
|
|
||||||
|
len =
|
||||||
|
String.length str
|
||||||
|
in
|
||||||
|
case points of
|
||||||
|
index :: [] ->
|
||||||
|
if index == (len - 3) then
|
||||||
|
String.toFloat str
|
||||||
|
|> Maybe.map Ok
|
||||||
|
|> Maybe.withDefault (Err "Two digits required after the dot.")
|
||||||
|
|
||||||
|
else
|
||||||
|
Err ("Two digits required after the dot: " ++ str)
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
Err "One single dot + digits required for money."
|
||||||
|
|
||||||
|
|
||||||
|
format : Float -> String
|
||||||
|
format money =
|
||||||
|
String.fromFloat (roundMoney money)
|
||||||
|
|
||||||
|
|
||||||
|
roundMoney : Float -> Float
|
||||||
|
roundMoney input =
|
||||||
|
(round (input * 100) |> toFloat) / 100
|
Loading…
x
Reference in New Issue
Block a user