diff --git a/part12/ElmHub.elm b/part12/ElmHub.elm index be5637d..1d3ff29 100644 --- a/part12/ElmHub.elm +++ b/part12/ElmHub.elm @@ -76,8 +76,6 @@ subscriptions _ = viewOptions : SearchOptions -> Html OptionsMsg viewOptions opts = - -- TODO add this line so we can tell whenever this function gets executed: - -- Debug.log "viewOptions was called" <| div [ class "search-options" ] [ div [ class "search-option" ] [ label [ class "top-label" ] [ text "Search in" ] @@ -92,6 +90,11 @@ viewOptions opts = , input [ type' "text" , placeholder "Enter a username" + -- TODO replace opts.userFilter with the following: + -- + -- (Debug.log "username" opts.userFilter) + -- + -- This way, we'll see console output whenever this gets run! , defaultValue opts.userFilter , onInput SetUserFilter ] @@ -229,9 +232,11 @@ view model = ] , div [ class "search" ] -- TODO change this to (lazy viewOptions model.options) - -- and verify that it no longer shows the Debug.log message every - -- time you type in the input box. Instead, it should only show - -- once on page load, and then again when the options change. + -- and verify that it no longer shows the Debug.log message when + -- you type in the main search box. + -- + -- Instead, the message should only appear once on page load, + -- and then again when interacting with the options themselves. [ Html.map Options (viewOptions model.options) , div [ class "search-input" ] [ input [ class "search-query", onInput SetQuery, defaultValue model.query ] [] diff --git a/part13/ElmHub.elm b/part13/ElmHub.elm index ba6bde6..f15fadc 100644 --- a/part13/ElmHub.elm +++ b/part13/ElmHub.elm @@ -35,9 +35,9 @@ type alias Model = type alias SearchOptions = - { sort : String - , ascending : Bool - , searchInDescription : Bool + { minStars : Int + , minStarsError : Maybe String + , searchIn : String , userFilter : String } @@ -55,9 +55,9 @@ initialModel = , results = [] , errorMessage = Nothing , options = - { sort = "stars" - , ascending = False - , searchInDescription = True + { minStars = 0 + , minStarsError = Nothing + , searchIn = "name" , userFilter = "" } , tableState = Table.initialSort "Stars" @@ -74,6 +74,50 @@ subscriptions _ = githubResponse decodeResponse +viewOptions : SearchOptions -> Html OptionsMsg +viewOptions opts = + div [ class "search-options" ] + [ div [ class "search-option" ] + [ label [ class "top-label" ] [ text "Search in" ] + , select [ onChange SetSearchIn, value opts.searchIn ] + [ option [ value "name" ] [ text "Name" ] + , option [ value "description" ] [ text "Description" ] + , option [ value "name,description" ] [ text "Name and Description" ] + ] + ] + , div [ class "search-option" ] + [ label [ class "top-label" ] [ text "Owned by" ] + , input + [ type' "text" + , placeholder "Enter a username" + , defaultValue (Debug.log "username" opts.userFilter) + , onInput SetUserFilter + ] + [] + ] + , div [ class "search-option" ] + [ label [ class "top-label" ] [ text "Minimum Stars" ] + , input + [ type' "text" + , onBlurWithTargetValue SetMinStars + , defaultValue (toString opts.minStars) + ] + [] + , viewMinStarsError opts.minStarsError + ] + ] + + +viewMinStarsError : Maybe String -> Html msg +viewMinStarsError message = + case message of + Nothing -> + text " " + + Just errorMessage -> + div [ class "stars-error" ] [ text errorMessage ] + + type Msg = Search | Options OptionsMsg @@ -121,6 +165,11 @@ update msg model = ( model, Cmd.none ) +onBlurWithTargetValue : (String -> msg) -> Attribute msg +onBlurWithTargetValue toMsg = + on "blur" (Json.Decode.map toMsg targetValue) + + tableConfig : Table.Config SearchResult Msg tableConfig = Table.config @@ -151,14 +200,19 @@ nameColumn = updateOptions : OptionsMsg -> SearchOptions -> SearchOptions updateOptions optionsMsg options = case optionsMsg of - SetSort sort -> - { options | sort = sort } + SetMinStars minStarsStr -> + case String.toInt minStarsStr of + Ok minStars -> + { options | minStars = minStars, minStarsError = Nothing } - SetAscending ascending -> - { options | ascending = ascending } + Err _ -> + { options + | minStarsError = + Just "Must be an integer!" + } - SetSearchInDescription searchInDescription -> - { options | searchInDescription = searchInDescription } + SetSearchIn searchIn -> + { options | searchIn = searchIn } SetUserFilter userFilter -> { options | userFilter = userFilter } @@ -210,44 +264,11 @@ viewSearchResult result = type OptionsMsg - = SetSort String - | SetAscending Bool - | SetSearchInDescription Bool + = SetMinStars String + | SetSearchIn String | SetUserFilter String -viewOptions : SearchOptions -> Html OptionsMsg -viewOptions opts = - div [ class "search-options" ] - [ div [ class "search-option" ] - [ label [ class "top-label" ] [ text "Sort by" ] - , select [ onChange SetSort, value opts.sort ] - [ option [ value "stars" ] [ text "Stars" ] - , option [ value "forks" ] [ text "Forks" ] - , option [ value "updated" ] [ text "Updated" ] - ] - ] - , div [ class "search-option" ] - [ label [ class "top-label" ] [ text "Owned by" ] - , input - [ type' "text" - , placeholder "Enter a username" - , defaultValue opts.userFilter - , onInput SetUserFilter - ] - [] - ] - , label [ class "search-option" ] - [ input [ type' "checkbox", checked opts.ascending, onCheck SetAscending ] [] - , text "Sort ascending" - ] - , label [ class "search-option" ] - [ input [ type' "checkbox", checked opts.searchInDescription, onCheck SetSearchInDescription ] [] - , text "Search in description" - ] - ] - - decodeGithubResponse : Json.Decode.Value -> Msg decodeGithubResponse value = case Json.Decode.decodeValue responseDecoder value of @@ -286,22 +307,13 @@ getQueryString model = ++ Auth.token ++ "&q=" ++ model.query - ++ (if model.options.searchInDescription then - "+in:name,description" - else - "+in:name" - ) + ++ "+in:" + ++ model.options.searchIn + ++ "+stars:>=" + ++ (toString model.options.minStars) ++ "+language:elm" ++ (if String.isEmpty model.options.userFilter then "" else "+user:" ++ model.options.userFilter ) - ++ "&sort=" - ++ model.options.sort - ++ "&order=" - ++ (if model.options.ascending then - "asc" - else - "desc" - ) diff --git a/part13/ElmHubCss.elm b/part13/ElmHubCss.elm index 3fccf0d..2422b7a 100644 --- a/part13/ElmHubCss.elm +++ b/part13/ElmHubCss.elm @@ -99,6 +99,15 @@ css = -- outline: none; -- } -- + -- .stars-error { + -- background-color: #FF9632; + -- font-size: 16px; + -- padding: 10px; + -- margin-right: 24px; + -- border-radius: 10px; + -- margin-top: 10px; + -- } + -- -- .error { -- background-color: #FF9632; -- padding: 20px; @@ -111,21 +120,22 @@ css = -- .search-input { -- display: block; -- float: left; - -- width: 50%; + -- width: 42%; -- } -- -- .search-options { -- position: relative; -- float: right; - -- width: 50%; + -- width: 58%; -- box-sizing: border-box; - -- padding: 20px; + -- padding-top: 20px; -- } -- -- .search-option { -- display: block; -- float: left; - -- width: 50%; + -- width: 30%; + -- margin-left: 16px; -- box-sizing: border-box; -- } --