forked from shibao/cannery
		
	add search to catalog index
This commit is contained in:
		@@ -20,11 +20,38 @@ defmodule Cannery.Ammo do
 | 
			
		||||
      iex> list_ammo_types(%User{id: 123})
 | 
			
		||||
      [%AmmoType{}, ...]
 | 
			
		||||
 | 
			
		||||
      iex> list_ammo_types("cool", %User{id: 123})
 | 
			
		||||
      [%AmmoType{name: "My cool ammo type"}, ...]
 | 
			
		||||
 | 
			
		||||
  """
 | 
			
		||||
  @spec list_ammo_types(User.t()) :: [AmmoType.t()]
 | 
			
		||||
  def list_ammo_types(%User{id: user_id}),
 | 
			
		||||
  @spec list_ammo_types(search :: nil | String.t(), User.t()) :: [AmmoType.t()]
 | 
			
		||||
  def list_ammo_types(search \\ nil, user)
 | 
			
		||||
 | 
			
		||||
  def list_ammo_types(search, %{id: user_id}) when search |> is_nil() or search == "",
 | 
			
		||||
    do: Repo.all(from at in AmmoType, where: at.user_id == ^user_id, order_by: at.name)
 | 
			
		||||
 | 
			
		||||
  def list_ammo_types(search, %{id: user_id}) when search |> is_binary() do
 | 
			
		||||
    trimmed_search = String.trim(search)
 | 
			
		||||
 | 
			
		||||
    Repo.all(
 | 
			
		||||
      from at in AmmoType,
 | 
			
		||||
        where: at.user_id == ^user_id,
 | 
			
		||||
        where:
 | 
			
		||||
          fragment(
 | 
			
		||||
            "search @@ websearch_to_tsquery('english', ?)",
 | 
			
		||||
            ^trimmed_search
 | 
			
		||||
          ),
 | 
			
		||||
        order_by: {
 | 
			
		||||
          :desc,
 | 
			
		||||
          fragment(
 | 
			
		||||
            "ts_rank_cd(search, websearch_to_tsquery('english', ?), 4)",
 | 
			
		||||
            ^trimmed_search
 | 
			
		||||
          )
 | 
			
		||||
        }
 | 
			
		||||
    )
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  @doc """
 | 
			
		||||
  Returns a count of ammo_types.
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -104,6 +104,7 @@ defmodule CanneryWeb do
 | 
			
		||||
 | 
			
		||||
      # credo:disable-for-next-line Credo.Check.Consistency.MultiAliasImportRequireUse
 | 
			
		||||
      import CanneryWeb.{ErrorHelpers, Gettext, LiveHelpers, ViewHelpers}
 | 
			
		||||
      alias CanneryWeb.Endpoint
 | 
			
		||||
      alias CanneryWeb.Router.Helpers, as: Routes
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 
 | 
			
		||||
@@ -4,13 +4,15 @@ defmodule CanneryWeb.AmmoTypeLive.Index do
 | 
			
		||||
  """
 | 
			
		||||
 | 
			
		||||
  use CanneryWeb, :live_view
 | 
			
		||||
 | 
			
		||||
  alias Cannery.{Ammo, Ammo.AmmoType}
 | 
			
		||||
  alias CanneryWeb.Endpoint
 | 
			
		||||
 | 
			
		||||
  @impl true
 | 
			
		||||
  def mount(%{"search" => search}, _session, socket) do
 | 
			
		||||
    {:ok, socket |> assign(show_used: false, search: search) |> list_ammo_types()}
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def mount(_params, _session, socket) do
 | 
			
		||||
    {:ok, socket |> assign(:show_used, false) |> list_ammo_types()}
 | 
			
		||||
    {:ok, socket |> assign(show_used: false, search: nil) |> list_ammo_types()}
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  @impl true
 | 
			
		||||
@@ -19,25 +21,49 @@ defmodule CanneryWeb.AmmoTypeLive.Index do
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  defp apply_action(%{assigns: %{current_user: current_user}} = socket, :edit, %{"id" => id}) do
 | 
			
		||||
    %{name: ammo_type_name} = ammo_type = Ammo.get_ammo_type!(id, current_user)
 | 
			
		||||
 | 
			
		||||
    socket
 | 
			
		||||
    |> assign(:page_title, gettext("Edit Ammo type"))
 | 
			
		||||
    |> assign(:ammo_type, Ammo.get_ammo_type!(id, current_user))
 | 
			
		||||
    |> assign(
 | 
			
		||||
      page_title: gettext("Edit %{ammo_type_name}", ammo_type_name: ammo_type_name),
 | 
			
		||||
      ammo_type: ammo_type
 | 
			
		||||
    )
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  defp apply_action(%{assigns: %{current_user: current_user}} = socket, :clone, %{"id" => id}) do
 | 
			
		||||
    socket
 | 
			
		||||
    |> assign(:page_title, gettext("New Ammo type"))
 | 
			
		||||
    |> assign(:ammo_type, %{Ammo.get_ammo_type!(id, current_user) | id: nil})
 | 
			
		||||
    |> assign(
 | 
			
		||||
      page_title: gettext("New Ammo type"),
 | 
			
		||||
      ammo_type: %{Ammo.get_ammo_type!(id, current_user) | id: nil}
 | 
			
		||||
    )
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  defp apply_action(socket, :new, _params) do
 | 
			
		||||
    socket
 | 
			
		||||
    |> assign(:page_title, gettext("New Ammo type"))
 | 
			
		||||
    |> assign(:ammo_type, %AmmoType{})
 | 
			
		||||
    |> assign(
 | 
			
		||||
      page_title: gettext("New Ammo type"),
 | 
			
		||||
      ammo_type: %AmmoType{}
 | 
			
		||||
    )
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  defp apply_action(socket, :index, _params) do
 | 
			
		||||
    socket |> assign(:page_title, gettext("Ammo types")) |> assign(:ammo_type, nil)
 | 
			
		||||
    socket
 | 
			
		||||
    |> assign(
 | 
			
		||||
      page_title: gettext("Catalog"),
 | 
			
		||||
      search: nil,
 | 
			
		||||
      ammo_type: nil
 | 
			
		||||
    )
 | 
			
		||||
    |> list_ammo_types()
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  defp apply_action(socket, :search, %{"search" => search}) do
 | 
			
		||||
    socket
 | 
			
		||||
    |> assign(
 | 
			
		||||
      page_title: gettext("Catalog"),
 | 
			
		||||
      search: search,
 | 
			
		||||
      ammo_type: nil
 | 
			
		||||
    )
 | 
			
		||||
    |> list_ammo_types()
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  @impl true
 | 
			
		||||
@@ -54,8 +80,20 @@ defmodule CanneryWeb.AmmoTypeLive.Index do
 | 
			
		||||
    {:noreply, socket |> assign(:show_used, !show_used) |> list_ammo_types()}
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  defp list_ammo_types(%{assigns: %{current_user: current_user, show_used: show_used}} = socket) do
 | 
			
		||||
    ammo_types = Ammo.list_ammo_types(current_user)
 | 
			
		||||
  @impl true
 | 
			
		||||
  def handle_event("search", %{"search" => %{"search_term" => ""}}, socket) do
 | 
			
		||||
    {:noreply, socket |> push_patch(to: Routes.ammo_type_index_path(Endpoint, :index))}
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def handle_event("search", %{"search" => %{"search_term" => search_term}}, socket) do
 | 
			
		||||
    {:noreply,
 | 
			
		||||
     socket |> push_patch(to: Routes.ammo_type_index_path(Endpoint, :search, search_term))}
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  defp list_ammo_types(
 | 
			
		||||
         %{assigns: %{search: search, current_user: current_user, show_used: show_used}} = socket
 | 
			
		||||
       ) do
 | 
			
		||||
    ammo_types = Ammo.list_ammo_types(search, current_user)
 | 
			
		||||
 | 
			
		||||
    columns =
 | 
			
		||||
      [
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,23 @@
 | 
			
		||||
      <%= dgettext("actions", "New Ammo type") %>
 | 
			
		||||
    </.link>
 | 
			
		||||
 | 
			
		||||
    <div class="flex flex-col justify-center items-center">
 | 
			
		||||
    <div class="w-full flex flex-col sm:flex-row justify-center items-center space-y-4 sm:space-y-0 sm:space-x-4 max-w-xl">
 | 
			
		||||
      <.form
 | 
			
		||||
        :let={f}
 | 
			
		||||
        for={:search}
 | 
			
		||||
        phx-change="search"
 | 
			
		||||
        phx-submit="search"
 | 
			
		||||
        class="grow self-stretch flex flex-col items-stretch"
 | 
			
		||||
        data-qa="ammo_type_search"
 | 
			
		||||
      >
 | 
			
		||||
        <%= text_input(f, :search_term,
 | 
			
		||||
          class: "input input-primary",
 | 
			
		||||
          value: @search,
 | 
			
		||||
          phx_debounce: 300,
 | 
			
		||||
          placeholder: gettext("Search catalog")
 | 
			
		||||
        ) %>
 | 
			
		||||
      </.form>
 | 
			
		||||
 | 
			
		||||
      <.toggle_button action="toggle_show_used" value={@show_used}>
 | 
			
		||||
        <span class="title text-lg text-primary-600">
 | 
			
		||||
          <%= gettext("Show used") %>
 | 
			
		||||
 
 | 
			
		||||
@@ -68,12 +68,13 @@ defmodule CanneryWeb.Router do
 | 
			
		||||
 | 
			
		||||
    live "/catalog", AmmoTypeLive.Index, :index
 | 
			
		||||
    live "/catalog/new", AmmoTypeLive.Index, :new
 | 
			
		||||
    live "/catalog/:id/clone", AmmoTypeLive.Index, :clone
 | 
			
		||||
    live "/catalog/:id/edit", AmmoTypeLive.Index, :edit
 | 
			
		||||
    live "/catalog/clone/:id", AmmoTypeLive.Index, :clone
 | 
			
		||||
    live "/catalog/edit/:id", AmmoTypeLive.Index, :edit
 | 
			
		||||
    live "/catalog/search/:search", AmmoTypeLive.Index, :search
 | 
			
		||||
 | 
			
		||||
    live "/catalog/:id/show", AmmoTypeLive.Show, :show
 | 
			
		||||
    live "/catalog/:id/show/edit", AmmoTypeLive.Show, :edit
 | 
			
		||||
    live "/catalog/:id/show/table", AmmoTypeLive.Show, :table
 | 
			
		||||
    live "/type/:id", AmmoTypeLive.Show, :show
 | 
			
		||||
    live "/type/:id/edit", AmmoTypeLive.Show, :edit
 | 
			
		||||
    live "/type/:id/table", AmmoTypeLive.Show, :table
 | 
			
		||||
 | 
			
		||||
    live "/containers", ContainerLive.Index, :index
 | 
			
		||||
    live "/containers/table", ContainerLive.Index, :table
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user