docspell/modules/webapp/src/main/elm/Comp/MappingForm.elm
2020-06-07 22:16:40 +02:00

182 lines
4.5 KiB
Elm

module Comp.MappingForm exposing
( FormData
, Model
, Msg
, ViewOpts
, init
, update
, view
)
import Comp.FixedDropdown
import Dict exposing (Dict)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onClick)
import Util.Maybe
type alias FormData =
Dict String String
type alias Model =
{ leftDropdown : Comp.FixedDropdown.Model String
, rightDropdown : Comp.FixedDropdown.Model String
, leftSelect : Maybe String
, rightSelect : Maybe String
}
type Msg
= AddPair FormData
| DeleteItem FormData String
| EditItem String String
| LeftMsg (Comp.FixedDropdown.Msg String)
| RightMsg (Comp.FixedDropdown.Msg String)
init : List String -> List String -> Model
init leftSel rightSel =
{ leftDropdown = Comp.FixedDropdown.initString leftSel
, rightDropdown = Comp.FixedDropdown.initString rightSel
, leftSelect = Nothing
, rightSelect = Nothing
}
--- Update
update : Msg -> Model -> ( Model, Maybe FormData )
update msg model =
case msg of
AddPair data ->
case ( model.leftSelect, model.rightSelect ) of
( Just l, Just r ) ->
( { model
| leftSelect = Nothing
, rightSelect = Nothing
}
, Just (Dict.insert l r data)
)
_ ->
( model, Nothing )
DeleteItem data k ->
( model, Just (Dict.remove k data) )
EditItem k v ->
( { model
| leftSelect = Just k
, rightSelect = Just v
}
, Nothing
)
LeftMsg lm ->
let
( m_, la ) =
Comp.FixedDropdown.update lm model.leftDropdown
in
( { model
| leftDropdown = m_
, leftSelect = Util.Maybe.withDefault model.leftSelect la
}
, Nothing
)
RightMsg lm ->
let
( m_, la ) =
Comp.FixedDropdown.update lm model.rightDropdown
in
( { model
| rightDropdown = m_
, rightSelect = Util.Maybe.withDefault model.rightSelect la
}
, Nothing
)
--- View
type alias ViewOpts =
{ renderItem : ( String, String ) -> Html Msg
, label : String
, description : Maybe String
}
view : FormData -> ViewOpts -> Model -> Html Msg
view data opts model =
div [ class "field" ]
[ label [] [ text opts.label ]
, div [ class "fields" ]
[ div [ class "inline field" ]
[ Html.map LeftMsg
(Comp.FixedDropdown.viewString
model.leftSelect
model.leftDropdown
)
]
, div [ class "inline field" ]
[ Html.map RightMsg
(Comp.FixedDropdown.viewString
model.rightSelect
model.rightDropdown
)
]
, button
[ class "ui icon button"
, onClick (AddPair data)
, href "#"
]
[ i [ class "add icon" ] []
]
]
, renderFormData opts data
, span
[ classList
[ ( "small-info", True )
, ( "invisible hidden", opts.description == Nothing )
]
]
[ Maybe.withDefault "" opts.description
|> text
]
]
renderFormData : ViewOpts -> FormData -> Html Msg
renderFormData opts data =
let
values =
Dict.toList data
renderItem ( k, v ) =
div [ class "item" ]
[ a
[ class "link icon"
, href "#"
, onClick (DeleteItem data k)
]
[ i [ class "trash icon" ] []
]
, a
[ class "link icon"
, href "#"
, onClick (EditItem k v)
]
[ i [ class "edit icon" ] []
]
, opts.renderItem ( k, v )
]
in
div [ class "ui list" ]
(List.map renderItem values)