module SideBar.View exposing (view) {-| Displays the SideBar @docs view -} import Html exposing (..) import Html.Attributes exposing (..) import Html.Events exposing (onClick, onInput, on) import InputTable.Messages exposing (..) import Json.Decode as Json import InputTable.Model exposing (..) import List.Extra exposing (find) import Array import Dict import String view : TableState rowData sideRowData -> RowId -> Bool -> Html (TableMsg rowData focussedData) view tableState rowId showNext = let headersAndResponses = case tableState.sideBarHeaders of Just headers -> List.map (getHtmlForDataType tableState rowId) headers Nothing -> [ div [] [] ] tableActionElem = case tableState.tableAction of Just title -> let rowTitle = tableState.rowIdsToTitles |> Dict.get rowId |> Maybe.withDefault "" in span [ class "sidebar__title" ] [ text <| title ++ ": " ++ rowTitle ] Nothing -> span [] [] in div [] [ div [ class "sidebar__section" ] [ tableActionElem , span [ class "sidebar__copy" ] [] , button [ class "sidebar__close-button" , onClick (ToggleSideBar tableState.sideBarRowId) ] [] , (if showNext then button [ class "button button--primary button--save-and-next" , onClick FocusOnNext ] [ text "Save And Next" ] else text "" ) , span [ class "sidebar__copy" ] [ text (case tableState.savingState of None -> "" Saving -> "Saving..." Saved -> "Saved" Error -> "Apologies, there was an error during saving" ) ] ] , div [ class "form" ] headersAndResponses ] getHtmlForDataType : TableState rowData sideRowData -> RowId -> SideBarHeader rowData -> Html (TableMsg rowData focussedData) getHtmlForDataType tableState rowId header = let row = tableState.rows |> find (\r -> r.id == rowId) in case row of Nothing -> text "" Just row -> case header.subType of SideBarDropdown props -> let viewOption optionsValue = option [ selected (optionsValue == (props.get row.data)) ] [ text optionsValue ] in div [ class "form__question-section" ] [ label [ class "form__label" ] [ text header.title ] , span [ class "form__hint form__hint--multi" ] [ text (Maybe.withDefault "" header.description) ] , select [ class "form__input form__input--dropdown" , onChange (SetCellValue header.id props.set row.id False) ] (List.map viewOption props.options) ] SideBarMenuDropdown props -> let viewOption i optionsValue = option [ selected (optionsValue == (props.get row.data)) , value optionsValue ] [ text (Maybe.withDefault "" (List.Extra.getAt i props.displayedTextOptions) ) ] in div [ class "form__question-section" ] [ label [ class "form__label" ] [ text header.title ] , span [ class "form__hint form__hint--multi" ] [ text (Maybe.withDefault "" header.description) ] , select [ class "form__input form__input--dropdown" , onChange (SetCellValue header.id props.set row.id False) ] (List.indexedMap viewOption props.options) ] SideBarCheckbox props -> div [ class "form__question-section" ] [ label [ class "form__label" ] [ text header.title ] , span [ class "form__hint form__hint--multi" ] [ text (Maybe.withDefault "" header.description) ] , input [ class "form__checkbox" , type_ "checkbox" , checked (props.get row.data) , onClick (SetBoolCellValue header.id props.set row.id (not (props.get row.data))) ] [] ] SideBarTextArea props -> div [ class "form__question-section" ] [ label [ class "form__label" ] [ text header.title ] , span [ class "form__hint form__hint--multi" ] [ text (Maybe.withDefault "" header.description) ] , textarea [ class "form__input form__input--textarea" , onChange (SetCellValue header.id props.set row.id False) , value (props.get row.data) ] [] ] SideBarTextInput props -> div [ class "form__question-section" ] [ label [ class "form__label" ] [ text header.title ] , span [ class "form__hint form__hint--multi" ] [ text (Maybe.withDefault "" header.description) ] , input [ class "form__input" , type_ "text" , onChange (SetCellValue header.id props.set row.id False) , value (props.get row.data) ] [] ] SideBarMultiRadioInput props -> let options = List.filter (\o -> not (String.isEmpty o)) props.options value optionsValue = (props.get row.data) == optionsValue viewOption optionsValue = label [ class "form__checkbox-label" ] [ input [ class "form__checkbox" , type_ "radio" , checked (value optionsValue) , onClick (SetCellValue header.id props.set row.id False optionsValue) ] [] , text optionsValue ] in div [ class "form__question-section" ] [ label [ class "form__label" ] [ text header.title ] , span [ class "form__hint form__hint--multi" ] [ text (Maybe.withDefault "" header.description) ] , span [] (List.map viewOption options) ] SideBarMultiCheckboxInput props -> let checkBoxResponses = props.get row.data options = List.filter ((/=) "") props.options inSelected optionsValue = List.member optionsValue (props.get row.data) --the responses are sent in the payload as a string, each response is separated by the string '*SPLITTER*' --to fix #4645 getNewResponses optionsValue = if (List.member optionsValue checkBoxResponses) then List.filter (\r -> r /= optionsValue) checkBoxResponses |> List.filter ((/=) "") |> String.join "*SPLITTER*" else optionsValue :: checkBoxResponses |> List.filter ((/=) "") |> String.join "*SPLITTER*" viewOption optionsValue = label [ class "form__checkbox-label" ] [ input [ class "form__checkbox" , type_ "checkbox" , checked (inSelected optionsValue) , onClick (SetCellValue header.id props.set row.id True (getNewResponses optionsValue)) ] [] , text optionsValue ] in div [ class "form__question-section" ] [ label [ class "form__label" ] [ text header.title ] , span [ class "form__hint form__hint--multi" ] [ text (Maybe.withDefault "" header.description) ] , span [] (List.map viewOption options) ] SideBarMceInputType1 props -> let divId = "question-header-" ++ header.id in div [ class "form__question-section" ] [ label [ class "form__label" ] [ text header.title ] , span [ class "form__hint form__hint--multi" ] [ text (Maybe.withDefault "" header.description) ] , textarea [ id divId , class "tinymce-type1 form__input form__input--textarea" , value (props.get row.data) ] [] ] SideBarMceInputType2 props -> let divId = "question-header-" ++ header.id in div [ class "form__question-section" ] [ label [ class "form__label" ] [ text header.title ] , span [ class "form__hint form__hint--multi" ] [ text (Maybe.withDefault "" header.description) ] , textarea [ id divId , class "tinymce-type2 form__input form__input--textarea" , value (props.get row.data) ] [] ] SideBarMceInputType3 props -> let divId = "question-header-" ++ header.id in div [ class "form__question-section" ] [ label [ class "form__label" ] [ text header.title ] , span [ class "form__hint form__hint--multi" ] [ text (Maybe.withDefault "" header.description) ] , textarea [ id divId , class "tinymce-type3 form__input form__input--textarea" , value (props.get row.data) ] [] ] SideBarMceInputType4 props -> let divId = "question-header-" ++ header.id in div [ class "form__question-section" ] [ label [ class "form__label" ] [ text header.title ] , span [ class "form__hint form__hint--multi" ] [ text (Maybe.withDefault "" header.description) ] , textarea [ id divId , class "tinymce-type4 form__input form__input--textarea" , value (props.get row.data) ] [] ] onChange : (String -> msg) -> Attribute msg onChange handler = on "change" <| Json.map handler <| Json.at [ "target", "value" ] Json.string