Enable searching across record sets
This commit is contained in:
@@ -21,6 +21,23 @@ defmodule MusicLibrary.RecordSets do
|
||||
Repo.aggregate(RecordSet, :count)
|
||||
end
|
||||
|
||||
def count_record_sets(query) do
|
||||
record_sets_search_query(query)
|
||||
|> Repo.aggregate(:count)
|
||||
end
|
||||
|
||||
def search_record_sets(query, opts \\ []) do
|
||||
offset = Keyword.get(opts, :offset, 0)
|
||||
limit = Keyword.get(opts, :limit, 20)
|
||||
|
||||
record_sets_search_query(query)
|
||||
|> order_by([rs], desc: rs.updated_at)
|
||||
|> offset(^offset)
|
||||
|> limit(^limit)
|
||||
|> preload(items: :record)
|
||||
|> Repo.all()
|
||||
end
|
||||
|
||||
def get_record_set!(id) do
|
||||
RecordSet
|
||||
|> Repo.get!(id)
|
||||
@@ -125,6 +142,37 @@ defmodule MusicLibrary.RecordSets do
|
||||
{:ok, get_record_set!(record_set.id)}
|
||||
end
|
||||
|
||||
defp record_sets_search_query(""), do: from(rs in RecordSet)
|
||||
|
||||
defp record_sets_search_query(query) do
|
||||
like_query = "%#{query}%"
|
||||
|
||||
from(rs in RecordSet,
|
||||
where:
|
||||
like(rs.name, ^like_query) or
|
||||
like(rs.description, ^like_query) or
|
||||
fragment(
|
||||
"""
|
||||
EXISTS (
|
||||
SELECT 1 FROM record_set_items AS i
|
||||
JOIN records AS r ON r.id = i.record_id
|
||||
WHERE i.record_set_id = ?
|
||||
AND (
|
||||
r.title LIKE ?
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM json_each(r.artists)
|
||||
WHERE json_extract(value, '$.name') LIKE ?
|
||||
)
|
||||
)
|
||||
)
|
||||
""",
|
||||
rs.id,
|
||||
^like_query,
|
||||
^like_query
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
defp recompact_positions(record_set_id) do
|
||||
items =
|
||||
from(i in RecordSetItem,
|
||||
|
||||
@@ -47,10 +47,12 @@ defmodule MusicLibraryWeb.RecordSetLive.Index do
|
||||
end
|
||||
|
||||
defp apply_action(socket, :index, params) do
|
||||
total_sets = RecordSets.count_record_sets()
|
||||
query = params["query"] || ""
|
||||
total_sets = RecordSets.count_record_sets(query)
|
||||
|
||||
list_params =
|
||||
@default_list_params
|
||||
|> merge_query(query)
|
||||
|> merge_pagination(params, total_sets)
|
||||
|
||||
load_and_assign_sets(socket, list_params)
|
||||
@@ -75,6 +77,10 @@ defmodule MusicLibraryWeb.RecordSetLive.Index do
|
||||
|> Map.put(:total_records, total_records)
|
||||
end
|
||||
|
||||
defp merge_query(params, query) do
|
||||
Map.put(params, :query, query)
|
||||
end
|
||||
|
||||
defp parse_page(nil), do: 1
|
||||
|
||||
defp parse_page(page) when is_binary(page) do
|
||||
@@ -101,7 +107,7 @@ defmodule MusicLibraryWeb.RecordSetLive.Index do
|
||||
offset = page_to_offset(list_params.page, list_params.page_size)
|
||||
|
||||
sets =
|
||||
RecordSets.list_record_sets(
|
||||
RecordSets.search_record_sets(list_params.query,
|
||||
offset: offset,
|
||||
limit: list_params.page_size
|
||||
)
|
||||
@@ -119,7 +125,8 @@ defmodule MusicLibraryWeb.RecordSetLive.Index do
|
||||
def back_path(list_params) do
|
||||
qs =
|
||||
list_params
|
||||
|> Map.take([:page, :page_size])
|
||||
|> Map.take([:query, :page, :page_size])
|
||||
|> Enum.filter(fn {_, v} -> v not in ["", nil] end)
|
||||
|
||||
~p"/record-sets?#{qs}"
|
||||
end
|
||||
@@ -152,6 +159,15 @@ defmodule MusicLibraryWeb.RecordSetLive.Index do
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_event("search", %{"query" => query}, socket) do
|
||||
qs =
|
||||
@default_list_params
|
||||
|> Map.put(:query, query)
|
||||
|> Map.take([:query, :page, :page_size])
|
||||
|
||||
{:noreply, push_patch(socket, to: ~p"/record-sets?#{qs}")}
|
||||
end
|
||||
|
||||
def handle_event("delete_set", %{"id" => id}, socket) do
|
||||
record_set = RecordSets.get_record_set!(id)
|
||||
{:ok, _} = RecordSets.delete_record_set(record_set)
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<.search_form query={@list_params.query} />
|
||||
|
||||
<div class="mt-6 space-y-6">
|
||||
<ul phx-update="stream" id="record-sets-list" class="space-y-6">
|
||||
<li
|
||||
@@ -69,7 +71,7 @@
|
||||
<.dropdown_link
|
||||
id={"set-actions-#{record_set.id}-edit"}
|
||||
patch={
|
||||
~p"/record-sets/#{record_set}/edit?#{Map.take(@list_params, [:page, :page_size])}"
|
||||
~p"/record-sets/#{record_set}/edit?#{Map.take(@list_params, [:query, :page, :page_size]) |> Enum.filter(fn {_, v} -> v not in ["", nil] end)}"
|
||||
}
|
||||
>
|
||||
{gettext("Edit")}
|
||||
|
||||
Reference in New Issue
Block a user