Allow to show results alphabetically (#133)

fixed #119
This commit is contained in:
Rok Garbas 2020-07-10 09:49:43 +02:00 committed by GitHub
parent 4173453098
commit cc5e4a540d
Failed to generate hash of commit
5 changed files with 178 additions and 21 deletions

View file

@ -127,6 +127,7 @@ submitQuery old ( new, cmd ) =
(Maybe.withDefault "" newModel.query) (Maybe.withDefault "" newModel.query)
newModel.from newModel.from
newModel.size newModel.size
newModel.sort
|> Cmd.map msg |> Cmd.map msg
] ]
) )
@ -183,7 +184,7 @@ changeRouteTo model url =
-- on the home page -- on the home page
( newModel, Browser.Navigation.pushUrl newModel.navKey "/packages" ) ( newModel, Browser.Navigation.pushUrl newModel.navKey "/packages" )
Just (Route.Packages channel query show from size) -> Just (Route.Packages channel query show from size sort) ->
let let
modelPage = modelPage =
case newModel.page of case newModel.page of
@ -193,11 +194,11 @@ changeRouteTo model url =
_ -> _ ->
Nothing Nothing
in in
Page.Packages.init channel query show from size modelPage Page.Packages.init channel query show from size sort modelPage
|> updateWith Packages PackagesMsg newModel |> updateWith Packages PackagesMsg newModel
|> submitQuery newModel |> submitQuery newModel
Just (Route.Options channel query show from size) -> Just (Route.Options channel query show from size sort) ->
let let
modelPage = modelPage =
case newModel.page of case newModel.page of
@ -207,7 +208,7 @@ changeRouteTo model url =
_ -> _ ->
Nothing Nothing
in in
Page.Options.init channel query show from size modelPage Page.Options.init channel query show from size sort modelPage
|> updateWith Options OptionsMsg newModel |> updateWith Options OptionsMsg newModel
|> submitQuery newModel |> submitQuery newModel

View file

@ -73,12 +73,13 @@ init :
-> Maybe String -> Maybe String
-> Maybe Int -> Maybe Int
-> Maybe Int -> Maybe Int
-> Maybe String
-> Maybe Model -> Maybe Model
-> ( Model, Cmd Msg ) -> ( Model, Cmd Msg )
init channel query show from size model = init channel query show from size sort model =
let let
( newModel, newCmd ) = ( newModel, newCmd ) =
Search.init channel query show from size model Search.init channel query show from size sort model
in in
( newModel ( newModel
, Cmd.map SearchMsg newCmd , Cmd.map SearchMsg newCmd
@ -285,8 +286,9 @@ makeRequest :
-> String -> String
-> Int -> Int
-> Int -> Int
-> Search.Sort
-> Cmd Msg -> Cmd Msg
makeRequest options channel queryRaw from size = makeRequest options channel queryRaw from size sort =
let let
query = query =
queryRaw queryRaw
@ -402,7 +404,7 @@ makeRequest options channel queryRaw from size =
|> List.append (should_match 10) |> List.append (should_match 10)
in in
Search.makeRequest Search.makeRequest
(Search.makeRequestBody query from size "option" "option_name_query" should_queries) (Search.makeRequestBody query from size sort "option" "option_name" "option_name_query" should_queries)
("latest-" ++ String.fromInt options.mappingSchemaVersion ++ "-" ++ channel) ("latest-" ++ String.fromInt options.mappingSchemaVersion ++ "-" ++ channel)
decodeResultItemSource decodeResultItemSource
options options

View file

@ -108,12 +108,13 @@ init :
-> Maybe String -> Maybe String
-> Maybe Int -> Maybe Int
-> Maybe Int -> Maybe Int
-> Maybe String
-> Maybe Model -> Maybe Model
-> ( Model, Cmd Msg ) -> ( Model, Cmd Msg )
init channel query show from size model = init channel query show from size sort model =
let let
( newModel, newCmd ) = ( newModel, newCmd ) =
Search.init channel query show from size model Search.init channel query show from size sort model
in in
( newModel ( newModel
, Cmd.map SearchMsg newCmd , Cmd.map SearchMsg newCmd
@ -381,8 +382,9 @@ makeRequest :
-> String -> String
-> Int -> Int
-> Int -> Int
-> Search.Sort
-> Cmd Msg -> Cmd Msg
makeRequest options channel queryRaw from size = makeRequest options channel queryRaw from size sort =
let let
query = query =
queryRaw queryRaw
@ -504,7 +506,7 @@ makeRequest options channel queryRaw from size =
|> List.append (should_match 10) |> List.append (should_match 10)
in in
Search.makeRequest Search.makeRequest
(Search.makeRequestBody query from size "package" "package_attr_name_query" should_queries) (Search.makeRequestBody query from size sort "package" "package_attr_name" "package_attr_name_query" should_queries)
("latest-" ++ String.fromInt options.mappingSchemaVersion ++ "-" ++ channel) ("latest-" ++ String.fromInt options.mappingSchemaVersion ++ "-" ++ channel)
decodeResultItemSource decodeResultItemSource
options options

View file

@ -15,8 +15,8 @@ import Url.Parser.Query
type Route type Route
= NotFound = NotFound
| Home | Home
| Packages (Maybe String) (Maybe String) (Maybe String) (Maybe Int) (Maybe Int) | Packages (Maybe String) (Maybe String) (Maybe String) (Maybe Int) (Maybe Int) (Maybe String)
| Options (Maybe String) (Maybe String) (Maybe String) (Maybe Int) (Maybe Int) | Options (Maybe String) (Maybe String) (Maybe String) (Maybe Int) (Maybe Int) (Maybe String)
parser : Url.Parser.Parser (Route -> msg) msg parser : Url.Parser.Parser (Route -> msg) msg
@ -36,6 +36,7 @@ parser =
<?> Url.Parser.Query.string "show" <?> Url.Parser.Query.string "show"
<?> Url.Parser.Query.int "from" <?> Url.Parser.Query.int "from"
<?> Url.Parser.Query.int "size" <?> Url.Parser.Query.int "size"
<?> Url.Parser.Query.string "sort"
) )
, Url.Parser.map , Url.Parser.map
Options Options
@ -45,6 +46,7 @@ parser =
<?> Url.Parser.Query.string "show" <?> Url.Parser.Query.string "show"
<?> Url.Parser.Query.int "from" <?> Url.Parser.Query.int "from"
<?> Url.Parser.Query.int "size" <?> Url.Parser.Query.int "size"
<?> Url.Parser.Query.string "sort"
) )
] ]
@ -94,22 +96,24 @@ routeToPieces page =
NotFound -> NotFound ->
( [ "not-found" ], [] ) ( [ "not-found" ], [] )
Packages channel query show from size -> Packages channel query show from size sort ->
( [ "packages" ] ( [ "packages" ]
, [ channel , [ channel
, query , query
, show , show
, Maybe.map String.fromInt from , Maybe.map String.fromInt from
, Maybe.map String.fromInt size , Maybe.map String.fromInt size
, sort
] ]
) )
Options channel query show from size -> Options channel query show from size sort ->
( [ "options" ] ( [ "options" ]
, [ channel , [ channel
, query , query
, show , show
, Maybe.map String.fromInt from , Maybe.map String.fromInt from
, Maybe.map String.fromInt size , Maybe.map String.fromInt size
, sort
] ]
) )

View file

@ -4,8 +4,10 @@ module Search exposing
, Options , Options
, ResultItem , ResultItem
, SearchResult , SearchResult
, Sort(..)
, channelDetailsFromId , channelDetailsFromId
, decodeResult , decodeResult
, fromSortId
, init , init
, makeRequest , makeRequest
, makeRequestBody , makeRequestBody
@ -30,8 +32,11 @@ import Html
, h1 , h1
, h4 , h4
, input , input
, label
, li , li
, option
, p , p
, select
, strong , strong
, text , text
, ul , ul
@ -46,6 +51,7 @@ import Html.Attributes
, href , href
, id , id
, placeholder , placeholder
, selected
, type_ , type_
, value , value
) )
@ -76,6 +82,7 @@ type alias Model a =
, show : Maybe String , show : Maybe String
, from : Int , from : Int
, size : Int , size : Int
, sort : Sort
} }
@ -114,22 +121,29 @@ type alias ResultHitsTotal =
type alias ResultItem a = type alias ResultItem a =
{ index : String { index : String
, id : String , id : String
, score : Float , score : Maybe Float
, source : a , source : a
, text : Maybe String , text : Maybe String
, matched_queries : Maybe (List String) , matched_queries : Maybe (List String)
} }
type Sort
= Relevance
| AlphabeticallyAsc
| AlphabeticallyDesc
init : init :
Maybe String Maybe String
-> Maybe String -> Maybe String
-> Maybe String -> Maybe String
-> Maybe Int -> Maybe Int
-> Maybe Int -> Maybe Int
-> Maybe String
-> Maybe (Model a) -> Maybe (Model a)
-> ( Model a, Cmd (Msg a) ) -> ( Model a, Cmd (Msg a) )
init channel query show from size model = init channel query show from size sort model =
let let
defaultChannel = defaultChannel =
model model
@ -173,6 +187,11 @@ init channel query show from size model =
, show = show , show = show
, from = Maybe.withDefault defaultFrom from , from = Maybe.withDefault defaultFrom from
, size = Maybe.withDefault defaultSize size , size = Maybe.withDefault defaultSize size
, sort =
sort
|> Maybe.withDefault ""
|> fromSortId
|> Maybe.withDefault Relevance
} }
, Browser.Dom.focus "search-query-input" |> Task.attempt (\_ -> NoOp) , Browser.Dom.focus "search-query-input" |> Task.attempt (\_ -> NoOp)
) )
@ -186,6 +205,7 @@ init channel query show from size model =
type Msg a type Msg a
= NoOp = NoOp
| SortChange String
| ChannelChange String | ChannelChange String
| QueryInputDebounce (Debouncer.Messages.Msg (Msg a)) | QueryInputDebounce (Debouncer.Messages.Msg (Msg a))
| QueryInput String | QueryInput String
@ -221,6 +241,23 @@ update path navKey result_type options decodeResultItemSource msg model =
, Cmd.none , Cmd.none
) )
SortChange sortId ->
let
sort =
fromSortId sortId |> Maybe.withDefault Relevance
in
( { model | sort = sort }
, createUrl
path
model.channel
model.query
model.show
0
model.size
sort
|> Browser.Navigation.pushUrl navKey
)
ChannelChange channel -> ChannelChange channel ->
( { model ( { model
| channel = channel | channel = channel
@ -242,6 +279,7 @@ update path navKey result_type options decodeResultItemSource msg model =
model.show model.show
0 0
model.size model.size
model.sort
|> Browser.Navigation.pushUrl navKey |> Browser.Navigation.pushUrl navKey
) )
@ -349,6 +387,7 @@ update path navKey result_type options decodeResultItemSource msg model =
model.show model.show
0 0
model.size model.size
model.sort
|> Browser.Navigation.pushUrl navKey |> Browser.Navigation.pushUrl navKey
) )
@ -371,6 +410,7 @@ update path navKey result_type options decodeResultItemSource msg model =
) )
model.from model.from
model.size model.size
model.sort
|> Browser.Navigation.pushUrl navKey |> Browser.Navigation.pushUrl navKey
) )
@ -531,10 +571,12 @@ createUrl :
-> Maybe String -> Maybe String
-> Int -> Int
-> Int -> Int
-> Sort
-> String -> String
createUrl path channel query show from size = createUrl path channel query show from size sort =
[ Url.Builder.int "from" from [ Url.Builder.int "from" from
, Url.Builder.int "size" size , Url.Builder.int "size" size
, Url.Builder.string "sort" <| toSortId sort
, Url.Builder.string "channel" channel , Url.Builder.string "channel" channel
] ]
|> List.append |> List.append
@ -618,6 +660,82 @@ channels =
] ]
sortBy : List Sort
sortBy =
[ Relevance
, AlphabeticallyAsc
, AlphabeticallyDesc
]
toSortQuery :
Sort
-> String
-> ( String, Json.Encode.Value )
toSortQuery sort field =
( "sort"
, case sort of
AlphabeticallyAsc ->
Json.Encode.list Json.Encode.object
[ [ ( field, Json.Encode.string "asc" )
]
]
AlphabeticallyDesc ->
Json.Encode.list Json.Encode.object
[ [ ( field, Json.Encode.string "desc" )
]
]
Relevance ->
Json.Encode.list Json.Encode.string
[ "_score"
]
)
toSortTitle : Sort -> String
toSortTitle sort =
case sort of
AlphabeticallyAsc ->
"Alphabetically Ascending"
AlphabeticallyDesc ->
"Alphabetically Descending"
Relevance ->
"Relevance"
toSortId : Sort -> String
toSortId sort =
case sort of
AlphabeticallyAsc ->
"alpha_asc"
AlphabeticallyDesc ->
"alpha_desc"
Relevance ->
"relevance"
fromSortId : String -> Maybe Sort
fromSortId id =
case id of
"alpha_asc" ->
Just AlphabeticallyAsc
"alpha_desc" ->
Just AlphabeticallyDesc
"relevance" ->
Just Relevance
_ ->
Nothing
getSuggestions : getSuggestions :
Maybe String Maybe String
-> RemoteData.WebData (SearchResult a) -> RemoteData.WebData (SearchResult a)
@ -840,6 +958,29 @@ view path title model viewSuccess outMsg =
) )
] ]
] ]
, form [ class "form-horizontal pull-right" ]
[ div
[ class "control-group"
]
[ label [ class "control-label" ] [ text "Sort by:" ]
, div
[ class "controls" ]
[ select
[ onInput (\x -> outMsg (SortChange x))
]
(List.map
(\sort ->
option
[ selected (model.sort == sort)
, value (toSortId sort)
]
[ text <| toSortTitle sort ]
)
sortBy
)
]
]
]
, viewPager outMsg model result path , viewPager outMsg model result path
, viewSuccess model.channel model.show result , viewSuccess model.channel model.show result
, viewPager outMsg model result path , viewPager outMsg model result path
@ -897,6 +1038,7 @@ viewPager _ model result path =
model.show model.show
0 0
model.size model.size
model.sort
] ]
[ text "First" ] [ text "First" ]
] ]
@ -918,6 +1060,7 @@ viewPager _ model result path =
model.show model.show
(model.from - model.size) (model.from - model.size)
model.size model.size
model.sort
] ]
[ text "Previous" ] [ text "Previous" ]
] ]
@ -939,6 +1082,7 @@ viewPager _ model result path =
model.show model.show
(model.from + model.size) (model.from + model.size)
model.size model.size
model.sort
] ]
[ text "Next" ] [ text "Next" ]
] ]
@ -968,6 +1112,7 @@ viewPager _ model result path =
model.show model.show
(((result.hits.total.value // model.size) - remainder) * model.size) (((result.hits.total.value // model.size) - remainder) * model.size)
model.size model.size
model.sort
] ]
[ text "Last" ] [ text "Last" ]
] ]
@ -1074,11 +1219,13 @@ makeRequestBody :
String String
-> Int -> Int
-> Int -> Int
-> Sort
-> String
-> String -> String
-> String -> String
-> List (List ( String, Json.Encode.Value )) -> List (List ( String, Json.Encode.Value ))
-> Http.Body -> Http.Body
makeRequestBody query from sizeRaw type_ query_field should_queries = makeRequestBody query from sizeRaw sort type_ sort_field query_field should_queries =
let let
-- you can not request more then 10000 results otherwise it will return 404 -- you can not request more then 10000 results otherwise it will return 404
size = size =
@ -1096,6 +1243,7 @@ makeRequestBody query from sizeRaw type_ query_field should_queries =
, ( "size" , ( "size"
, Json.Encode.int size , Json.Encode.int size
) )
, toSortQuery sort sort_field
, ( "query" , ( "query"
, Json.Encode.object , Json.Encode.object
[ ( "bool" [ ( "bool"
@ -1191,7 +1339,7 @@ decodeResultItem decodeResultItemSource =
Json.Decode.map6 ResultItem Json.Decode.map6 ResultItem
(Json.Decode.field "_index" Json.Decode.string) (Json.Decode.field "_index" Json.Decode.string)
(Json.Decode.field "_id" Json.Decode.string) (Json.Decode.field "_id" Json.Decode.string)
(Json.Decode.field "_score" Json.Decode.float) (Json.Decode.field "_score" (Json.Decode.nullable Json.Decode.float))
(Json.Decode.field "_source" decodeResultItemSource) (Json.Decode.field "_source" decodeResultItemSource)
(Json.Decode.maybe (Json.Decode.field "text" Json.Decode.string)) (Json.Decode.maybe (Json.Decode.field "text" Json.Decode.string))
(Json.Decode.maybe (Json.Decode.field "matched_queries" (Json.Decode.list Json.Decode.string))) (Json.Decode.maybe (Json.Decode.field "matched_queries" (Json.Decode.list Json.Decode.string)))