diff --git a/modules/webapp/src/main/elm/Comp/FixedDropdown.elm b/modules/webapp/src/main/elm/Comp/FixedDropdown.elm new file mode 100644 index 00000000..586dff32 --- /dev/null +++ b/modules/webapp/src/main/elm/Comp/FixedDropdown.elm @@ -0,0 +1,108 @@ +module Comp.FixedDropdown exposing + ( Item + , Model + , Msg + , init + , initMap + , initString + , initTuple + , update + , view + ) + +import Html exposing (..) +import Html.Attributes exposing (..) +import Html.Events exposing (onClick) + + +type alias Item a = + { id : a + , display : String + } + + +type alias Model a = + { options : List (Item a) + , menuOpen : Bool + } + + +type Msg a + = SelectItem (Item a) + | ToggleMenu + + +init : List (Item a) -> Model a +init options = + { options = options + , menuOpen = False + } + + +initString : List String -> Model String +initString strings = + init <| List.map (\s -> Item s s) strings + + +initMap : (a -> String) -> List a -> Model a +initMap elToString els = + init <| List.map (\a -> Item a (elToString a)) els + + +initTuple : List ( String, a ) -> Model a +initTuple tuples = + let + mkItem ( txt, id ) = + Item id txt + in + init <| List.map mkItem tuples + + +update : Msg a -> Model a -> ( Model a, Maybe a ) +update msg model = + case msg of + ToggleMenu -> + ( { model | menuOpen = not model.menuOpen }, Nothing ) + + SelectItem item -> + ( model, Just item.id ) + + +view : Maybe (Item a) -> Model a -> Html (Msg a) +view selected model = + div + [ classList + [ ( "ui selection dropdown", True ) + , ( "open", model.menuOpen ) + ] + , onClick ToggleMenu + ] + [ input [ type_ "hidden" ] [] + , i [ class "dropdown icon" ] [] + , div + [ classList + [ ( "default", selected == Nothing ) + , ( "text", True ) + ] + ] + [ Maybe.map .display selected + |> Maybe.withDefault "Select…" + |> text + ] + , div + [ classList + [ ( "menu transition", True ) + , ( "hidden", not model.menuOpen ) + , ( "visible", model.menuOpen ) + ] + ] + <| + List.map renderItems model.options + ] + + +renderItems : Item a -> Html (Msg a) +renderItems item = + div [ class "item", onClick (SelectItem item) ] + [ text item.display + ] diff --git a/modules/webapp/src/main/elm/Comp/SourceForm.elm b/modules/webapp/src/main/elm/Comp/SourceForm.elm index d0ba0a4d..73e7ee17 100644 --- a/modules/webapp/src/main/elm/Comp/SourceForm.elm +++ b/modules/webapp/src/main/elm/Comp/SourceForm.elm @@ -9,7 +9,7 @@ module Comp.SourceForm exposing ) import Api.Model.Source exposing (Source) -import Comp.Dropdown +import Comp.FixedDropdown import Data.Flags exposing (Flags) import Data.Priority exposing (Priority) import Html exposing (..) @@ -21,7 +21,8 @@ type alias Model = { source : Source , abbrev : String , description : Maybe String - , priority : Comp.Dropdown.Model Priority + , priorityModel : Comp.FixedDropdown.Model Priority + , priority : Priority , enabled : Bool } @@ -31,13 +32,11 @@ emptyModel = { source = Api.Model.Source.empty , abbrev = "" , description = Nothing - , priority = - Comp.Dropdown.makeSingleList - { makeOption = \p -> { text = Data.Priority.toName p, value = Data.Priority.toName p } - , placeholder = "" - , options = Data.Priority.all - , selected = Nothing - } + , priorityModel = + Comp.FixedDropdown.initMap + Data.Priority.toName + Data.Priority.all + , priority = Data.Priority.Low , enabled = False } @@ -57,11 +56,7 @@ getSource model = | abbrev = model.abbrev , description = model.description , enabled = model.enabled - , priority = - Comp.Dropdown.getSelected model.priority - |> List.head - |> Maybe.map Data.Priority.toName - |> Maybe.withDefault s.priority + , priority = Data.Priority.toName model.priority } @@ -70,7 +65,7 @@ type Msg | SetSource Source | SetDescr String | ToggleEnabled - | PrioDropdownMsg (Comp.Dropdown.Msg Priority) + | PrioDropdownMsg (Comp.FixedDropdown.Msg Priority) update : Flags -> Msg -> Model -> ( Model, Cmd Msg ) @@ -95,12 +90,8 @@ update _ msg model = , abbrev = t.abbrev , description = t.description , priority = - Comp.Dropdown.makeSingleList - { makeOption = \p -> { text = Data.Priority.toName p, value = Data.Priority.toName p } - , placeholder = "" - , options = Data.Priority.all - , selected = Data.Priority.fromString t.priority - } + Data.Priority.fromString t.priority + |> Maybe.withDefault Data.Priority.Low , enabled = t.enabled } , Cmd.none @@ -126,14 +117,25 @@ update _ msg model = PrioDropdownMsg m -> let - ( m2, c2 ) = - Comp.Dropdown.update m model.priority + ( m2, p2 ) = + Comp.FixedDropdown.update m model.priorityModel in - ( { model | priority = m2 }, Cmd.map PrioDropdownMsg c2 ) + ( { model + | priorityModel = m2 + , priority = Maybe.withDefault model.priority p2 + } + , Cmd.none + ) view : Flags -> Model -> Html Msg view flags model = + let + priorityItem = + Comp.FixedDropdown.Item + model.priority + (Data.Priority.toName model.priority) + in div [ class "ui form" ] [ div [ classList @@ -171,7 +173,11 @@ view flags model = ] , div [ class "field" ] [ label [] [ text "Priority" ] - , Html.map PrioDropdownMsg (Comp.Dropdown.view model.priority) + , Html.map PrioDropdownMsg + (Comp.FixedDropdown.view + (Just priorityItem) + model.priorityModel + ) ] , urlInfoMessage flags model ]