mirror of
https://github.com/plausible/analytics.git
synced 2024-09-11 18:07:33 +03:00
Refine ComboBox.StaticSearch (#3172)
This commit makes static search more strict by rejecting matches with a score less than 0.6. Here's an example of suggestion that was matching with a 0.5 score that should not be suggested. This makes the suggestion list smaller and more reasonable. Co-authored by: Robert Joonas <robertjoonas16@gmail.com>
This commit is contained in:
parent
a9603a44c9
commit
60e418b357
@ -252,16 +252,15 @@ defmodule PlausibleWeb.Live.Components.ComboBox do
|
||||
socket
|
||||
end
|
||||
|
||||
if input_len > 0 do
|
||||
suggestions =
|
||||
input
|
||||
|> suggest_mod.suggest(options)
|
||||
|> Enum.take(suggestions_limit(socket.assigns))
|
||||
suggestions =
|
||||
if input_len > 0 do
|
||||
suggest_mod.suggest(input, options)
|
||||
else
|
||||
options
|
||||
end
|
||||
|> Enum.take(suggestions_limit(socket.assigns))
|
||||
|
||||
{:noreply, assign(socket, %{suggestions: suggestions})}
|
||||
else
|
||||
{:noreply, socket}
|
||||
end
|
||||
{:noreply, assign(socket, %{suggestions: suggestions})}
|
||||
end
|
||||
|
||||
defp do_select(socket, submit_value, display_value) do
|
||||
|
@ -11,25 +11,28 @@ defmodule PlausibleWeb.Live.Components.ComboBox.StaticSearch do
|
||||
|
||||
@spec suggest(String.t(), [{any(), any()}]) :: [{any(), any()}]
|
||||
def suggest(input, options) do
|
||||
input_len = String.length(input)
|
||||
|
||||
options
|
||||
|> Enum.reject(fn {_, value} ->
|
||||
input_len > String.length(to_string(value))
|
||||
end)
|
||||
|> Enum.sort_by(
|
||||
fn {_, value} ->
|
||||
if to_string(value) == input do
|
||||
3
|
||||
else
|
||||
value = to_string(value)
|
||||
input = String.downcase(input)
|
||||
value = String.downcase(value)
|
||||
weight = if String.contains?(value, input), do: 1, else: 0
|
||||
weight + String.jaro_distance(value, input)
|
||||
end
|
||||
end,
|
||||
:desc
|
||||
)
|
||||
|> Enum.map(fn {_, value} = option -> {option, weight(value, input)} end)
|
||||
|> Enum.reject(fn {_option, weight} -> weight < 0.6 end)
|
||||
|> Enum.sort_by(fn {_option, weight} -> weight end, :desc)
|
||||
|> Enum.map(fn {option, _weight} -> option end)
|
||||
end
|
||||
|
||||
defp weight(value, input) do
|
||||
value = to_string(value)
|
||||
|
||||
case {value, input} do
|
||||
{value, input} when value == input ->
|
||||
3
|
||||
|
||||
{value, input} when byte_size(input) > byte_size(value) ->
|
||||
0
|
||||
|
||||
{value, input} ->
|
||||
input = String.downcase(input)
|
||||
value = String.downcase(value)
|
||||
weight = if String.contains?(value, input), do: 1, else: 0
|
||||
weight + String.jaro_distance(value, input)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -24,9 +24,12 @@ defmodule PlausibleWeb.Live.Components.ComboBox.StaticSearchTest do
|
||||
|
||||
test "allows fuzzy matching" do
|
||||
options = fake_options(["/url/0xC0FFEE", "/url/0xDEADBEEF", "/url/other"])
|
||||
assert [{_, "/url/0xC0FFEE"}] = StaticSearch.suggest("0x FF", options)
|
||||
end
|
||||
|
||||
assert [{_, "/url/0xC0FFEE"}, {_, "/url/0xDEADBEEF"}, {_, "/url/other"}] =
|
||||
StaticSearch.suggest("0x FF", options)
|
||||
test "filters out bad matches" do
|
||||
options = fake_options(["OS", "Version", "Logged In"])
|
||||
assert [] = StaticSearch.suggest("cow", options)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -191,6 +191,14 @@ defmodule PlausibleWeb.Live.Components.ComboBoxTest do
|
||||
refute element_exists?(doc, suggestion_li(8))
|
||||
refute element_exists?(doc, suggestion_li(9))
|
||||
end
|
||||
|
||||
test "clearing search input resets to all options", %{conn: conn} do
|
||||
{:ok, lv, _html} = live_isolated(conn, SampleView, session: %{})
|
||||
type_into_combo(lv, "test-component", "Echo me")
|
||||
doc = type_into_combo(lv, "test-component", "")
|
||||
|
||||
for i <- 1..7, do: assert(element_exists?(doc, suggestion_li(i)))
|
||||
end
|
||||
end
|
||||
|
||||
describe "creatable integration" do
|
||||
|
@ -56,9 +56,6 @@ defmodule PlausibleWeb.Live.FunnelSettings.FormTest do
|
||||
doc = type_into_combo(lv, 2, "another")
|
||||
|
||||
refute text_of_element(doc, "ul#dropdown-step-1 li") =~ "Another World"
|
||||
|
||||
assert text_of_element(doc, "ul#dropdown-step-2 li") =~ "Hello World"
|
||||
assert text_of_element(doc, "ul#dropdown-step-2 li") =~ "Plausible"
|
||||
refute text_of_element(doc, "ul#dropdown-step-2 li") =~ "Another World"
|
||||
end
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user