diff --git a/CHANGELOG.md b/CHANGELOG.md
index 085d45ec..0c2ef1f0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,6 @@
# v0.8.0
-- Add search to catalog
-- Tweak urls for ammo types
+- Add search to catalog and ammo
+- Tweak urls for catalog and ammo
# v0.7.2
- Code improvements
diff --git a/lib/cannery/ammo.ex b/lib/cannery/ammo.ex
index d7d5b963..ece49a80 100644
--- a/lib/cannery/ammo.ex
+++ b/lib/cannery/ammo.ex
@@ -421,36 +421,86 @@ defmodule Cannery.Ammo do
end
@doc """
- Returns the list of ammo_groups for a user.
+ Returns the list of ammo_groups.
## Examples
iex> list_ammo_groups(%User{id: 123})
[%AmmoGroup{}, ...]
+ iex> list_ammo_groups("cool", true, %User{id: 123})
+ [%AmmoGroup{notes: "My cool ammo group"}, ...]
+
"""
@spec list_ammo_groups(User.t()) :: [AmmoGroup.t()]
- @spec list_ammo_groups(User.t(), include_empty :: boolean()) :: [AmmoGroup.t()]
- def list_ammo_groups(user, include_empty \\ false)
-
- def list_ammo_groups(%User{id: user_id}, true = _include_empty) do
- Repo.all(
- from ag in AmmoGroup,
- left_join: sg in assoc(ag, :shot_groups),
- where: ag.user_id == ^user_id,
- preload: [shot_groups: sg],
- order_by: ag.id
+ @spec list_ammo_groups(search :: nil | String.t(), User.t()) :: [AmmoGroup.t()]
+ @spec list_ammo_groups(search :: nil | String.t(), include_empty :: boolean(), User.t()) ::
+ [AmmoGroup.t()]
+ def list_ammo_groups(search \\ nil, include_empty \\ false, %{id: user_id}) do
+ from(
+ ag in AmmoGroup,
+ as: :ag,
+ left_join: sg in assoc(ag, :shot_groups),
+ as: :sg,
+ join: at in assoc(ag, :ammo_type),
+ as: :at,
+ join: c in assoc(ag, :container),
+ as: :c,
+ left_join: t in assoc(c, :tags),
+ as: :t,
+ where: ag.user_id == ^user_id,
+ preload: [shot_groups: sg, ammo_type: at, container: {c, tags: t}],
+ order_by: ag.id
)
+ |> list_ammo_groups_include_empty(include_empty)
+ |> list_ammo_groups_search(search)
+ |> Repo.all()
end
- def list_ammo_groups(%User{id: user_id}, false = _include_empty) do
- Repo.all(
- from ag in AmmoGroup,
- left_join: sg in assoc(ag, :shot_groups),
- where: ag.user_id == ^user_id,
- where: not (ag.count == 0),
- preload: [shot_groups: sg],
- order_by: ag.id
+ defp list_ammo_groups_include_empty(query, true), do: query
+
+ defp list_ammo_groups_include_empty(query, false) do
+ query |> where([ag], not (ag.count == 0))
+ end
+
+ defp list_ammo_groups_search(query, nil), do: query
+ defp list_ammo_groups_search(query, ""), do: query
+
+ defp list_ammo_groups_search(query, search) do
+ trimmed_search = String.trim(search)
+
+ query
+ |> where(
+ [ag: ag, at: at, c: c, t: t],
+ fragment(
+ "? @@ websearch_to_tsquery('english', ?)",
+ ag.search,
+ ^trimmed_search
+ ) or
+ fragment(
+ "? @@ websearch_to_tsquery('english', ?)",
+ at.search,
+ ^trimmed_search
+ ) or
+ fragment(
+ "? @@ websearch_to_tsquery('english', ?)",
+ c.search,
+ ^trimmed_search
+ ) or
+ fragment(
+ "? @@ websearch_to_tsquery('english', ?)",
+ t.search,
+ ^trimmed_search
+ )
+ )
+ |> order_by(
+ [ag: ag],
+ desc:
+ fragment(
+ "ts_rank_cd(?, websearch_to_tsquery('english', ?), 4)",
+ ag.search,
+ ^trimmed_search
+ )
)
end
diff --git a/lib/cannery_web/controllers/export_controller.ex b/lib/cannery_web/controllers/export_controller.ex
index a55218f0..3b62316f 100644
--- a/lib/cannery_web/controllers/export_controller.ex
+++ b/lib/cannery_web/controllers/export_controller.ex
@@ -23,7 +23,7 @@ defmodule CanneryWeb.ExportController do
end)
ammo_groups =
- Ammo.list_ammo_groups(current_user, true)
+ Ammo.list_ammo_groups(nil, true, current_user)
|> Enum.map(fn ammo_group ->
cpr = ammo_group |> Ammo.get_cpr()
used_count = ammo_group |> Ammo.get_used_count()
diff --git a/lib/cannery_web/live/ammo_group_live/index.ex b/lib/cannery_web/live/ammo_group_live/index.ex
index 0f4c1830..9ce5f9df 100644
--- a/lib/cannery_web/live/ammo_group_live/index.ex
+++ b/lib/cannery_web/live/ammo_group_live/index.ex
@@ -4,12 +4,15 @@ defmodule CanneryWeb.AmmoGroupLive.Index do
"""
use CanneryWeb, :live_view
- alias Cannery.{Ammo, Ammo.AmmoGroup, Containers, Repo}
- alias CanneryWeb.Endpoint
+ alias Cannery.{Ammo, Ammo.AmmoGroup, Containers}
@impl true
+ def mount(%{"search" => search}, _session, socket) do
+ {:ok, socket |> assign(show_used: false, search: search) |> display_ammo_groups()}
+ end
+
def mount(_params, _session, socket) do
- {:ok, socket |> assign(show_used: false)}
+ {:ok, socket |> assign(show_used: false, search: nil) |> display_ammo_groups()}
end
@impl true
@@ -23,38 +26,60 @@ defmodule CanneryWeb.AmmoGroupLive.Index do
%{"id" => id}
) do
socket
- |> assign(:page_title, gettext("Record shots"))
- |> assign(:ammo_group, Ammo.get_ammo_group!(id, current_user))
+ |> assign(
+ page_title: gettext("Record shots"),
+ ammo_group: Ammo.get_ammo_group!(id, current_user)
+ )
end
defp apply_action(%{assigns: %{current_user: current_user}} = socket, :move, %{"id" => id}) do
socket
- |> assign(:page_title, gettext("Move ammo"))
- |> assign(:ammo_group, Ammo.get_ammo_group!(id, current_user))
+ |> assign(
+ page_title: gettext("Move ammo"),
+ ammo_group: Ammo.get_ammo_group!(id, current_user)
+ )
end
defp apply_action(%{assigns: %{current_user: current_user}} = socket, :edit, %{"id" => id}) do
socket
- |> assign(:page_title, gettext("Edit ammo"))
- |> assign(:ammo_group, Ammo.get_ammo_group!(id, current_user))
+ |> assign(
+ page_title: gettext("Edit ammo"),
+ ammo_group: Ammo.get_ammo_group!(id, current_user)
+ )
end
defp apply_action(%{assigns: %{current_user: current_user}} = socket, :clone, %{"id" => id}) do
socket
- |> assign(:page_title, dgettext("actions", "Add Ammo"))
- |> assign(:ammo_group, %{Ammo.get_ammo_group!(id, current_user) | id: nil})
+ |> assign(
+ page_title: dgettext("actions", "Add Ammo"),
+ ammo_group: %{Ammo.get_ammo_group!(id, current_user) | id: nil}
+ )
end
defp apply_action(socket, :new, _params) do
socket
- |> assign(:page_title, dgettext("actions", "Add Ammo"))
- |> assign(:ammo_group, %AmmoGroup{})
+ |> assign(
+ page_title: dgettext("actions", "Add Ammo"),
+ ammo_group: %AmmoGroup{}
+ )
end
defp apply_action(socket, :index, _params) do
socket
- |> assign(:page_title, gettext("Ammo"))
- |> assign(:ammo_group, nil)
+ |> assign(
+ page_title: gettext("Ammo"),
+ search: nil,
+ ammo_group: nil
+ )
+ end
+
+ defp apply_action(socket, :search, %{"search" => search}) do
+ socket
+ |> assign(
+ page_title: gettext("Ammo"),
+ search: search,
+ ammo_group: nil
+ )
end
@impl true
@@ -85,13 +110,22 @@ defmodule CanneryWeb.AmmoGroupLive.Index do
{:noreply, socket |> assign(:show_used, !show_used) |> display_ammo_groups()}
end
- defp display_ammo_groups(
- %{assigns: %{current_user: current_user, show_used: show_used}} = socket
- ) do
- ammo_groups =
- Ammo.list_ammo_groups(current_user, show_used)
- |> Repo.preload([:ammo_type, :container], force: true)
+ @impl true
+ def handle_event("search", %{"search" => %{"search_term" => ""}}, socket) do
+ {:noreply, socket |> push_patch(to: Routes.ammo_group_index_path(Endpoint, :index))}
+ end
+ def handle_event("search", %{"search" => %{"search_term" => search_term}}, socket) do
+ socket =
+ socket |> push_patch(to: Routes.ammo_group_index_path(Endpoint, :search, search_term))
+
+ {:noreply, socket}
+ end
+
+ defp display_ammo_groups(
+ %{assigns: %{search: search, current_user: current_user, show_used: show_used}} = socket
+ ) do
+ ammo_groups = Ammo.list_ammo_groups(search, show_used, current_user)
ammo_types_count = Ammo.get_ammo_types_count!(current_user)
containers_count = Containers.get_containers_count!(current_user)
diff --git a/lib/cannery_web/live/ammo_group_live/index.html.heex b/lib/cannery_web/live/ammo_group_live/index.html.heex
index 85c50f86..c64c3570 100644
--- a/lib/cannery_web/live/ammo_group_live/index.html.heex
+++ b/lib/cannery_web/live/ammo_group_live/index.html.heex
@@ -3,7 +3,7 @@
<%= gettext("Ammo") %>
- <%= if @ammo_groups |> Enum.empty?() do %>
+ <%= if @ammo_groups |> Enum.empty?() and @search |> is_nil() do %>
<%= gettext("No Ammo") %>
<%= display_emoji("😔") %>
@@ -31,7 +31,7 @@
<%= dgettext("actions", "add an ammo type first") %>
- <% @ammo_groups |> Enum.empty?() -> %>
+ <% @ammo_groups |> Enum.empty?() and @search |> is_nil() -> %>
<.link patch={Routes.ammo_group_index_path(Endpoint, :new)} class="btn btn-primary">
<%= dgettext("actions", "Add your first box!") %>
@@ -41,15 +41,36 @@
<% end %>
- <%= unless @ammo_groups |> Enum.empty?() do %>
-
- <.toggle_button action="toggle_show_used" value={@show_used}>
-
- <%= gettext("Show used") %>
-
-
-
+
+ <.form
+ :let={f}
+ for={:search}
+ phx-change="search"
+ phx-submit="search"
+ class="grow self-stretch flex flex-col items-stretch"
+ data-qa="ammo_group_search"
+ >
+ <%= text_input(f, :search_term,
+ class: "input input-primary",
+ value: @search,
+ phx_debounce: 300,
+ placeholder: gettext("Search ammo")
+ ) %>
+
+ <.toggle_button action="toggle_show_used" value={@show_used}>
+
+ <%= gettext("Show used") %>
+
+
+
+
+ <%= if @ammo_groups |> Enum.empty?() do %>
+
+ <%= gettext("No Ammo") %>
+ <%= display_emoji("😔") %>
+
+ <% else %>
<.live_component
module={CanneryWeb.Components.AmmoGroupTableComponent}
id="ammo-group-index-table"
diff --git a/lib/cannery_web/router.ex b/lib/cannery_web/router.ex
index ecfa4157..fcd2b1c0 100644
--- a/lib/cannery_web/router.ex
+++ b/lib/cannery_web/router.ex
@@ -90,16 +90,17 @@ defmodule CanneryWeb.Router do
live "/ammo", AmmoGroupLive.Index, :index
live "/ammo/new", AmmoGroupLive.Index, :new
- live "/ammo/:id/edit", AmmoGroupLive.Index, :edit
- live "/ammo/:id/clone", AmmoGroupLive.Index, :clone
- live "/ammo/:id/add_shot_group", AmmoGroupLive.Index, :add_shot_group
- live "/ammo/:id/move", AmmoGroupLive.Index, :move
+ live "/ammo/edit/:id", AmmoGroupLive.Index, :edit
+ live "/ammo/clone/:id", AmmoGroupLive.Index, :clone
+ live "/ammo/add_shot_group/:id", AmmoGroupLive.Index, :add_shot_group
+ live "/ammo/move/:id", AmmoGroupLive.Index, :move
+ live "/ammo/search/:search", AmmoGroupLive.Index, :search
- live "/ammo/:id/show", AmmoGroupLive.Show, :show
- live "/ammo/:id/show/edit", AmmoGroupLive.Show, :edit
- live "/ammo/:id/show/add_shot_group", AmmoGroupLive.Show, :add_shot_group
- live "/ammo/:id/show/move", AmmoGroupLive.Show, :move
- live "/ammo/:id/show/:shot_group_id/edit", AmmoGroupLive.Show, :edit_shot_group
+ live "/ammo/show/:id", AmmoGroupLive.Show, :show
+ live "/ammo/show/edit/:id", AmmoGroupLive.Show, :edit
+ live "/ammo/show/add_shot_group/:id", AmmoGroupLive.Show, :add_shot_group
+ live "/ammo/show/move/:id", AmmoGroupLive.Show, :move
+ live "/ammo/show/:id/edit/:shot_group_id", AmmoGroupLive.Show, :edit_shot_group
live "/range", RangeLive.Index, :index
live "/range/:id/edit", RangeLive.Index, :edit
diff --git a/priv/gettext/actions.pot b/priv/gettext/actions.pot
index 8f3dc52c..cc8cc148 100644
--- a/priv/gettext/actions.pot
+++ b/priv/gettext/actions.pot
@@ -10,8 +10,8 @@
msgid ""
msgstr ""
-#: lib/cannery_web/live/ammo_group_live/index.ex:44
-#: lib/cannery_web/live/ammo_group_live/index.ex:50
+#: lib/cannery_web/live/ammo_group_live/index.ex:54
+#: lib/cannery_web/live/ammo_group_live/index.ex:62
#: lib/cannery_web/live/ammo_group_live/index.html.heex:40
#, elixir-autogen, elixir-format
msgid "Add Ammo"
@@ -156,7 +156,7 @@ msgstr ""
msgid "Why not get some ready to shoot?"
msgstr ""
-#: lib/cannery_web/live/ammo_group_live/index.html.heex:79
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:100
#: lib/cannery_web/live/ammo_group_live/show.html.heex:101
#: lib/cannery_web/live/range_live/index.html.heex:38
#, elixir-autogen, elixir-format
diff --git a/priv/gettext/de/LC_MESSAGES/actions.po b/priv/gettext/de/LC_MESSAGES/actions.po
index 7b427afb..6f792d2d 100644
--- a/priv/gettext/de/LC_MESSAGES/actions.po
+++ b/priv/gettext/de/LC_MESSAGES/actions.po
@@ -23,8 +23,8 @@ msgstr ""
## Run "mix gettext.extract" to bring this file up to
## date. Leave "msgstr"s empty as changing them here has no
## effect: edit them in PO (.po) files instead.
-#: lib/cannery_web/live/ammo_group_live/index.ex:44
-#: lib/cannery_web/live/ammo_group_live/index.ex:50
+#: lib/cannery_web/live/ammo_group_live/index.ex:54
+#: lib/cannery_web/live/ammo_group_live/index.ex:62
#: lib/cannery_web/live/ammo_group_live/index.html.heex:40
#, elixir-autogen, elixir-format
msgid "Add Ammo"
@@ -169,7 +169,7 @@ msgstr "Munition markieren"
msgid "Why not get some ready to shoot?"
msgstr "Warum nicht einige für den Schießstand auswählen?"
-#: lib/cannery_web/live/ammo_group_live/index.html.heex:79
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:100
#: lib/cannery_web/live/ammo_group_live/show.html.heex:101
#: lib/cannery_web/live/range_live/index.html.heex:38
#, elixir-autogen, elixir-format
diff --git a/priv/gettext/de/LC_MESSAGES/default.po b/priv/gettext/de/LC_MESSAGES/default.po
index bae16150..4ca76e90 100644
--- a/priv/gettext/de/LC_MESSAGES/default.po
+++ b/priv/gettext/de/LC_MESSAGES/default.po
@@ -46,7 +46,8 @@ msgid "Admins:"
msgstr "Admins:"
#: lib/cannery_web/components/topbar.ex:73
-#: lib/cannery_web/live/ammo_group_live/index.ex:56
+#: lib/cannery_web/live/ammo_group_live/index.ex:70
+#: lib/cannery_web/live/ammo_group_live/index.ex:79
#: lib/cannery_web/live/ammo_group_live/index.html.heex:3
#: lib/cannery_web/live/range_live/index.ex:80
#, elixir-autogen, elixir-format
@@ -282,6 +283,7 @@ msgid "New Tag"
msgstr "Neuer Tag"
#: lib/cannery_web/live/ammo_group_live/index.html.heex:8
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:70
#, elixir-autogen, elixir-format
msgid "No Ammo"
msgstr "Keine Munition"
@@ -491,7 +493,7 @@ msgid "No ammo staged"
msgstr "Keine Munition selektiert"
#: lib/cannery_web/components/add_shot_group_component.html.heex:3
-#: lib/cannery_web/live/ammo_group_live/index.ex:26
+#: lib/cannery_web/live/ammo_group_live/index.ex:30
#, elixir-autogen, elixir-format
msgid "Record shots"
msgstr "Schüsse dokumentieren"
@@ -530,8 +532,8 @@ msgstr "Patronen abgefeuert"
msgid "Shot Records"
msgstr "Schießkladde"
-#: lib/cannery_web/live/ammo_group_live/index.ex:32
-#: lib/cannery_web/live/ammo_group_live/index.html.heex:96
+#: lib/cannery_web/live/ammo_group_live/index.ex:38
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:117
#, elixir-autogen, elixir-format
msgid "Move ammo"
msgstr "Munition verschieben"
@@ -609,12 +611,12 @@ msgstr "Derzeitiges Passwort"
msgid "New password"
msgstr "Neues Passwort"
-#: lib/cannery_web/live/ammo_group_live/index.html.heex:72
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:93
#, elixir-autogen, elixir-format
msgid "Stage"
msgstr "Markiert"
-#: lib/cannery_web/live/ammo_group_live/index.html.heex:72
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:93
#, elixir-autogen, elixir-format
msgid "Unstage"
msgstr "Demarkiert"
@@ -841,7 +843,7 @@ msgstr ""
msgid "Container:"
msgstr "Behälter"
-#: lib/cannery_web/live/ammo_group_live/index.html.heex:48
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:63
#: lib/cannery_web/live/ammo_type_live/index.html.heex:39
#: lib/cannery_web/live/ammo_type_live/show.html.heex:152
#: lib/cannery_web/live/container_live/show.html.heex:105
@@ -1104,7 +1106,7 @@ msgstr ""
msgid "Purchased on:"
msgstr ""
-#: lib/cannery_web/live/ammo_group_live/index.ex:38
+#: lib/cannery_web/live/ammo_group_live/index.ex:46
#, elixir-autogen, elixir-format, fuzzy
msgid "Edit ammo"
msgstr "Munitionstyp bearbeiten"
@@ -1119,3 +1121,8 @@ msgstr "Keine Munitionsarten"
#, elixir-autogen, elixir-format
msgid "Search catalog"
msgstr ""
+
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:57
+#, elixir-autogen, elixir-format, fuzzy
+msgid "Search ammo"
+msgstr ""
diff --git a/priv/gettext/de/LC_MESSAGES/errors.po b/priv/gettext/de/LC_MESSAGES/errors.po
index 6f965b13..51d016fe 100644
--- a/priv/gettext/de/LC_MESSAGES/errors.po
+++ b/priv/gettext/de/LC_MESSAGES/errors.po
@@ -187,7 +187,7 @@ msgstr ""
"Ungültige Nummer an Kopien. Muss zwischen 1 and %{max} liegen. War "
"%{multiplier}"
-#: lib/cannery/ammo.ex:636
+#: lib/cannery/ammo.ex:686
#, elixir-autogen, elixir-format
msgid "Invalid multiplier"
msgstr ""
diff --git a/priv/gettext/de/LC_MESSAGES/prompts.po b/priv/gettext/de/LC_MESSAGES/prompts.po
index 49b66f5f..8cbf214e 100644
--- a/priv/gettext/de/LC_MESSAGES/prompts.po
+++ b/priv/gettext/de/LC_MESSAGES/prompts.po
@@ -95,7 +95,7 @@ msgstr "Sind Sie sicher, dass sie %{name} löschen möchten?"
msgid "Are you sure you want to delete the invite for %{name}?"
msgstr "Sind Sie sicher, dass sie die Einladung für %{name} löschen möchten?"
-#: lib/cannery_web/live/ammo_group_live/index.html.heex:131
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:152
#: lib/cannery_web/live/ammo_group_live/show.html.heex:75
#, elixir-autogen, elixir-format
msgid "Are you sure you want to delete this ammo?"
@@ -266,7 +266,7 @@ msgstr "Möchten Sie die Sprache wechseln?"
msgid "Language updated successfully."
msgstr "Spracheinstellung gespeichert."
-#: lib/cannery_web/live/ammo_group_live/index.ex:64
+#: lib/cannery_web/live/ammo_group_live/index.ex:89
#: lib/cannery_web/live/ammo_group_live/show.ex:55
#, elixir-autogen, elixir-format, fuzzy
msgid "Ammo deleted succesfully"
diff --git a/priv/gettext/default.pot b/priv/gettext/default.pot
index a7278b61..d10f946a 100644
--- a/priv/gettext/default.pot
+++ b/priv/gettext/default.pot
@@ -31,7 +31,8 @@ msgid "Admins:"
msgstr ""
#: lib/cannery_web/components/topbar.ex:73
-#: lib/cannery_web/live/ammo_group_live/index.ex:56
+#: lib/cannery_web/live/ammo_group_live/index.ex:70
+#: lib/cannery_web/live/ammo_group_live/index.ex:79
#: lib/cannery_web/live/ammo_group_live/index.html.heex:3
#: lib/cannery_web/live/range_live/index.ex:80
#, elixir-autogen, elixir-format
@@ -267,6 +268,7 @@ msgid "New Tag"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:8
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:70
#, elixir-autogen, elixir-format
msgid "No Ammo"
msgstr ""
@@ -474,7 +476,7 @@ msgid "No ammo staged"
msgstr ""
#: lib/cannery_web/components/add_shot_group_component.html.heex:3
-#: lib/cannery_web/live/ammo_group_live/index.ex:26
+#: lib/cannery_web/live/ammo_group_live/index.ex:30
#, elixir-autogen, elixir-format
msgid "Record shots"
msgstr ""
@@ -513,8 +515,8 @@ msgstr ""
msgid "Shot Records"
msgstr ""
-#: lib/cannery_web/live/ammo_group_live/index.ex:32
-#: lib/cannery_web/live/ammo_group_live/index.html.heex:96
+#: lib/cannery_web/live/ammo_group_live/index.ex:38
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:117
#, elixir-autogen, elixir-format
msgid "Move ammo"
msgstr ""
@@ -592,12 +594,12 @@ msgstr ""
msgid "New password"
msgstr ""
-#: lib/cannery_web/live/ammo_group_live/index.html.heex:72
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:93
#, elixir-autogen, elixir-format
msgid "Stage"
msgstr ""
-#: lib/cannery_web/live/ammo_group_live/index.html.heex:72
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:93
#, elixir-autogen, elixir-format
msgid "Unstage"
msgstr ""
@@ -824,7 +826,7 @@ msgstr ""
msgid "Container:"
msgstr ""
-#: lib/cannery_web/live/ammo_group_live/index.html.heex:48
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:63
#: lib/cannery_web/live/ammo_type_live/index.html.heex:39
#: lib/cannery_web/live/ammo_type_live/show.html.heex:152
#: lib/cannery_web/live/container_live/show.html.heex:105
@@ -1087,7 +1089,7 @@ msgstr ""
msgid "Purchased on:"
msgstr ""
-#: lib/cannery_web/live/ammo_group_live/index.ex:38
+#: lib/cannery_web/live/ammo_group_live/index.ex:46
#, elixir-autogen, elixir-format
msgid "Edit ammo"
msgstr ""
@@ -1102,3 +1104,8 @@ msgstr ""
#, elixir-autogen, elixir-format
msgid "Search catalog"
msgstr ""
+
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:57
+#, elixir-autogen, elixir-format
+msgid "Search ammo"
+msgstr ""
diff --git a/priv/gettext/en/LC_MESSAGES/actions.po b/priv/gettext/en/LC_MESSAGES/actions.po
index 8a73e03f..84bcc4c6 100644
--- a/priv/gettext/en/LC_MESSAGES/actions.po
+++ b/priv/gettext/en/LC_MESSAGES/actions.po
@@ -11,8 +11,8 @@ msgstr ""
"Language: en\n"
"Plural-Forms: nplurals=2\n"
-#: lib/cannery_web/live/ammo_group_live/index.ex:44
-#: lib/cannery_web/live/ammo_group_live/index.ex:50
+#: lib/cannery_web/live/ammo_group_live/index.ex:54
+#: lib/cannery_web/live/ammo_group_live/index.ex:62
#: lib/cannery_web/live/ammo_group_live/index.html.heex:40
#, elixir-autogen, elixir-format
msgid "Add Ammo"
@@ -157,7 +157,7 @@ msgstr ""
msgid "Why not get some ready to shoot?"
msgstr ""
-#: lib/cannery_web/live/ammo_group_live/index.html.heex:79
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:100
#: lib/cannery_web/live/ammo_group_live/show.html.heex:101
#: lib/cannery_web/live/range_live/index.html.heex:38
#, elixir-autogen, elixir-format
diff --git a/priv/gettext/en/LC_MESSAGES/default.po b/priv/gettext/en/LC_MESSAGES/default.po
index 1f443b25..9163298e 100644
--- a/priv/gettext/en/LC_MESSAGES/default.po
+++ b/priv/gettext/en/LC_MESSAGES/default.po
@@ -32,7 +32,8 @@ msgid "Admins:"
msgstr ""
#: lib/cannery_web/components/topbar.ex:73
-#: lib/cannery_web/live/ammo_group_live/index.ex:56
+#: lib/cannery_web/live/ammo_group_live/index.ex:70
+#: lib/cannery_web/live/ammo_group_live/index.ex:79
#: lib/cannery_web/live/ammo_group_live/index.html.heex:3
#: lib/cannery_web/live/range_live/index.ex:80
#, elixir-autogen, elixir-format
@@ -268,6 +269,7 @@ msgid "New Tag"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:8
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:70
#, elixir-autogen, elixir-format
msgid "No Ammo"
msgstr ""
@@ -475,7 +477,7 @@ msgid "No ammo staged"
msgstr ""
#: lib/cannery_web/components/add_shot_group_component.html.heex:3
-#: lib/cannery_web/live/ammo_group_live/index.ex:26
+#: lib/cannery_web/live/ammo_group_live/index.ex:30
#, elixir-autogen, elixir-format
msgid "Record shots"
msgstr ""
@@ -514,8 +516,8 @@ msgstr ""
msgid "Shot Records"
msgstr ""
-#: lib/cannery_web/live/ammo_group_live/index.ex:32
-#: lib/cannery_web/live/ammo_group_live/index.html.heex:96
+#: lib/cannery_web/live/ammo_group_live/index.ex:38
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:117
#, elixir-autogen, elixir-format
msgid "Move ammo"
msgstr ""
@@ -593,12 +595,12 @@ msgstr ""
msgid "New password"
msgstr ""
-#: lib/cannery_web/live/ammo_group_live/index.html.heex:72
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:93
#, elixir-autogen, elixir-format
msgid "Stage"
msgstr ""
-#: lib/cannery_web/live/ammo_group_live/index.html.heex:72
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:93
#, elixir-autogen, elixir-format
msgid "Unstage"
msgstr ""
@@ -825,7 +827,7 @@ msgstr ""
msgid "Container:"
msgstr ""
-#: lib/cannery_web/live/ammo_group_live/index.html.heex:48
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:63
#: lib/cannery_web/live/ammo_type_live/index.html.heex:39
#: lib/cannery_web/live/ammo_type_live/show.html.heex:152
#: lib/cannery_web/live/container_live/show.html.heex:105
@@ -1088,7 +1090,7 @@ msgstr ""
msgid "Purchased on:"
msgstr ""
-#: lib/cannery_web/live/ammo_group_live/index.ex:38
+#: lib/cannery_web/live/ammo_group_live/index.ex:46
#, elixir-autogen, elixir-format, fuzzy
msgid "Edit ammo"
msgstr ""
@@ -1103,3 +1105,8 @@ msgstr ""
#, elixir-autogen, elixir-format
msgid "Search catalog"
msgstr ""
+
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:57
+#, elixir-autogen, elixir-format, fuzzy
+msgid "Search ammo"
+msgstr ""
diff --git a/priv/gettext/en/LC_MESSAGES/errors.po b/priv/gettext/en/LC_MESSAGES/errors.po
index 0ea6a60e..30fec662 100644
--- a/priv/gettext/en/LC_MESSAGES/errors.po
+++ b/priv/gettext/en/LC_MESSAGES/errors.po
@@ -170,7 +170,7 @@ msgstr ""
msgid "Invalid number of copies, must be between 1 and %{max}. Was %{multiplier}"
msgstr ""
-#: lib/cannery/ammo.ex:636
+#: lib/cannery/ammo.ex:686
#, elixir-autogen, elixir-format
msgid "Invalid multiplier"
msgstr ""
diff --git a/priv/gettext/en/LC_MESSAGES/prompts.po b/priv/gettext/en/LC_MESSAGES/prompts.po
index 32b70332..8f87df10 100644
--- a/priv/gettext/en/LC_MESSAGES/prompts.po
+++ b/priv/gettext/en/LC_MESSAGES/prompts.po
@@ -81,7 +81,7 @@ msgstr ""
msgid "Are you sure you want to delete the invite for %{name}?"
msgstr ""
-#: lib/cannery_web/live/ammo_group_live/index.html.heex:131
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:152
#: lib/cannery_web/live/ammo_group_live/show.html.heex:75
#, elixir-autogen, elixir-format
msgid "Are you sure you want to delete this ammo?"
@@ -246,7 +246,7 @@ msgstr ""
msgid "Language updated successfully."
msgstr ""
-#: lib/cannery_web/live/ammo_group_live/index.ex:64
+#: lib/cannery_web/live/ammo_group_live/index.ex:89
#: lib/cannery_web/live/ammo_group_live/show.ex:55
#, elixir-autogen, elixir-format, fuzzy
msgid "Ammo deleted succesfully"
diff --git a/priv/gettext/errors.pot b/priv/gettext/errors.pot
index 30b7152f..3d7f3d9e 100644
--- a/priv/gettext/errors.pot
+++ b/priv/gettext/errors.pot
@@ -169,7 +169,7 @@ msgstr ""
msgid "Invalid number of copies, must be between 1 and %{max}. Was %{multiplier}"
msgstr ""
-#: lib/cannery/ammo.ex:636
+#: lib/cannery/ammo.ex:686
#, elixir-autogen, elixir-format
msgid "Invalid multiplier"
msgstr ""
diff --git a/priv/gettext/es/LC_MESSAGES/actions.po b/priv/gettext/es/LC_MESSAGES/actions.po
index 40a4fa93..2ef2b96d 100644
--- a/priv/gettext/es/LC_MESSAGES/actions.po
+++ b/priv/gettext/es/LC_MESSAGES/actions.po
@@ -23,8 +23,8 @@ msgstr ""
## Run "mix gettext.extract" to bring this file up to
## date. Leave "msgstr"s empty as changing them here has no
## effect: edit them in PO (.po) files instead.
-#: lib/cannery_web/live/ammo_group_live/index.ex:44
-#: lib/cannery_web/live/ammo_group_live/index.ex:50
+#: lib/cannery_web/live/ammo_group_live/index.ex:54
+#: lib/cannery_web/live/ammo_group_live/index.ex:62
#: lib/cannery_web/live/ammo_group_live/index.html.heex:40
#, elixir-autogen, elixir-format
msgid "Add Ammo"
@@ -169,7 +169,7 @@ msgstr "Preparar munición"
msgid "Why not get some ready to shoot?"
msgstr "¿Por qué no preparar parte para disparar?"
-#: lib/cannery_web/live/ammo_group_live/index.html.heex:79
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:100
#: lib/cannery_web/live/ammo_group_live/show.html.heex:101
#: lib/cannery_web/live/range_live/index.html.heex:38
#, elixir-autogen, elixir-format
diff --git a/priv/gettext/es/LC_MESSAGES/default.po b/priv/gettext/es/LC_MESSAGES/default.po
index b02cde3a..c6bdab5a 100644
--- a/priv/gettext/es/LC_MESSAGES/default.po
+++ b/priv/gettext/es/LC_MESSAGES/default.po
@@ -46,7 +46,8 @@ msgid "Admins:"
msgstr ""
#: lib/cannery_web/components/topbar.ex:73
-#: lib/cannery_web/live/ammo_group_live/index.ex:56
+#: lib/cannery_web/live/ammo_group_live/index.ex:70
+#: lib/cannery_web/live/ammo_group_live/index.ex:79
#: lib/cannery_web/live/ammo_group_live/index.html.heex:3
#: lib/cannery_web/live/range_live/index.ex:80
#, elixir-autogen, elixir-format
@@ -282,6 +283,7 @@ msgid "New Tag"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:8
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:70
#, elixir-autogen, elixir-format
msgid "No Ammo"
msgstr ""
@@ -489,7 +491,7 @@ msgid "No ammo staged"
msgstr ""
#: lib/cannery_web/components/add_shot_group_component.html.heex:3
-#: lib/cannery_web/live/ammo_group_live/index.ex:26
+#: lib/cannery_web/live/ammo_group_live/index.ex:30
#, elixir-autogen, elixir-format
msgid "Record shots"
msgstr ""
@@ -528,8 +530,8 @@ msgstr ""
msgid "Shot Records"
msgstr ""
-#: lib/cannery_web/live/ammo_group_live/index.ex:32
-#: lib/cannery_web/live/ammo_group_live/index.html.heex:96
+#: lib/cannery_web/live/ammo_group_live/index.ex:38
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:117
#, elixir-autogen, elixir-format
msgid "Move ammo"
msgstr ""
@@ -607,12 +609,12 @@ msgstr ""
msgid "New password"
msgstr ""
-#: lib/cannery_web/live/ammo_group_live/index.html.heex:72
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:93
#, elixir-autogen, elixir-format
msgid "Stage"
msgstr ""
-#: lib/cannery_web/live/ammo_group_live/index.html.heex:72
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:93
#, elixir-autogen, elixir-format
msgid "Unstage"
msgstr ""
@@ -839,7 +841,7 @@ msgstr ""
msgid "Container:"
msgstr ""
-#: lib/cannery_web/live/ammo_group_live/index.html.heex:48
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:63
#: lib/cannery_web/live/ammo_type_live/index.html.heex:39
#: lib/cannery_web/live/ammo_type_live/show.html.heex:152
#: lib/cannery_web/live/container_live/show.html.heex:105
@@ -1102,7 +1104,7 @@ msgstr ""
msgid "Purchased on:"
msgstr ""
-#: lib/cannery_web/live/ammo_group_live/index.ex:38
+#: lib/cannery_web/live/ammo_group_live/index.ex:46
#, elixir-autogen, elixir-format, fuzzy
msgid "Edit ammo"
msgstr ""
@@ -1117,3 +1119,8 @@ msgstr ""
#, elixir-autogen, elixir-format
msgid "Search catalog"
msgstr ""
+
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:57
+#, elixir-autogen, elixir-format, fuzzy
+msgid "Search ammo"
+msgstr ""
diff --git a/priv/gettext/es/LC_MESSAGES/errors.po b/priv/gettext/es/LC_MESSAGES/errors.po
index 91925748..29697b63 100644
--- a/priv/gettext/es/LC_MESSAGES/errors.po
+++ b/priv/gettext/es/LC_MESSAGES/errors.po
@@ -185,7 +185,7 @@ msgstr "No se pudo analizar el número de copias"
msgid "Invalid number of copies, must be between 1 and %{max}. Was %{multiplier}"
msgstr "Número inválido de copias, debe ser entre 1 y %{max}. Fue %{multiplier"
-#: lib/cannery/ammo.ex:636
+#: lib/cannery/ammo.ex:686
#, elixir-autogen, elixir-format
msgid "Invalid multiplier"
msgstr "Multiplicador inválido"
diff --git a/priv/gettext/es/LC_MESSAGES/prompts.po b/priv/gettext/es/LC_MESSAGES/prompts.po
index f5f7d425..25b92161 100644
--- a/priv/gettext/es/LC_MESSAGES/prompts.po
+++ b/priv/gettext/es/LC_MESSAGES/prompts.po
@@ -95,7 +95,7 @@ msgstr "Está seguro que desea eliminar %{name}?"
msgid "Are you sure you want to delete the invite for %{name}?"
msgstr "Está seguro que quiere eliminar la invitación para %{name}?"
-#: lib/cannery_web/live/ammo_group_live/index.html.heex:131
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:152
#: lib/cannery_web/live/ammo_group_live/show.html.heex:75
#, elixir-autogen, elixir-format
msgid "Are you sure you want to delete this ammo?"
@@ -265,7 +265,7 @@ msgstr ""
msgid "Language updated successfully."
msgstr ""
-#: lib/cannery_web/live/ammo_group_live/index.ex:64
+#: lib/cannery_web/live/ammo_group_live/index.ex:89
#: lib/cannery_web/live/ammo_group_live/show.ex:55
#, elixir-autogen, elixir-format, fuzzy
msgid "Ammo deleted succesfully"
diff --git a/priv/gettext/fr/LC_MESSAGES/actions.po b/priv/gettext/fr/LC_MESSAGES/actions.po
index 4903c0dc..73528783 100644
--- a/priv/gettext/fr/LC_MESSAGES/actions.po
+++ b/priv/gettext/fr/LC_MESSAGES/actions.po
@@ -23,8 +23,8 @@ msgstr ""
# # Run "mix gettext.extract" to bring this file up to
# # date. Leave "msgstr"s empty as changing them here has no
# # effect: edit them in PO (.po) files instead.
-#: lib/cannery_web/live/ammo_group_live/index.ex:44
-#: lib/cannery_web/live/ammo_group_live/index.ex:50
+#: lib/cannery_web/live/ammo_group_live/index.ex:54
+#: lib/cannery_web/live/ammo_group_live/index.ex:62
#: lib/cannery_web/live/ammo_group_live/index.html.heex:40
#, elixir-autogen, elixir-format
msgid "Add Ammo"
@@ -169,7 +169,7 @@ msgstr "Munition préparée"
msgid "Why not get some ready to shoot?"
msgstr "Pourquoi pas en préparer pour tirer ?"
-#: lib/cannery_web/live/ammo_group_live/index.html.heex:79
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:100
#: lib/cannery_web/live/ammo_group_live/show.html.heex:101
#: lib/cannery_web/live/range_live/index.html.heex:38
#, elixir-autogen, elixir-format
diff --git a/priv/gettext/fr/LC_MESSAGES/default.po b/priv/gettext/fr/LC_MESSAGES/default.po
index 7fd506b4..df9747e2 100644
--- a/priv/gettext/fr/LC_MESSAGES/default.po
+++ b/priv/gettext/fr/LC_MESSAGES/default.po
@@ -46,7 +46,8 @@ msgid "Admins:"
msgstr "Administrateur·ices :"
#: lib/cannery_web/components/topbar.ex:73
-#: lib/cannery_web/live/ammo_group_live/index.ex:56
+#: lib/cannery_web/live/ammo_group_live/index.ex:70
+#: lib/cannery_web/live/ammo_group_live/index.ex:79
#: lib/cannery_web/live/ammo_group_live/index.html.heex:3
#: lib/cannery_web/live/range_live/index.ex:80
#, elixir-autogen, elixir-format
@@ -282,6 +283,7 @@ msgid "New Tag"
msgstr "Nouveau tag"
#: lib/cannery_web/live/ammo_group_live/index.html.heex:8
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:70
#, elixir-autogen, elixir-format
msgid "No Ammo"
msgstr "Aucune munition"
@@ -493,7 +495,7 @@ msgid "No ammo staged"
msgstr "Aucune munition sélectionnée"
#: lib/cannery_web/components/add_shot_group_component.html.heex:3
-#: lib/cannery_web/live/ammo_group_live/index.ex:26
+#: lib/cannery_web/live/ammo_group_live/index.ex:30
#, elixir-autogen, elixir-format
msgid "Record shots"
msgstr "Tirs enregistrés"
@@ -532,8 +534,8 @@ msgstr "Cartouches tirées"
msgid "Shot Records"
msgstr "Enregistrements de tir"
-#: lib/cannery_web/live/ammo_group_live/index.ex:32
-#: lib/cannery_web/live/ammo_group_live/index.html.heex:96
+#: lib/cannery_web/live/ammo_group_live/index.ex:38
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:117
#, elixir-autogen, elixir-format
msgid "Move ammo"
msgstr "Déplacer munition"
@@ -611,12 +613,12 @@ msgstr "Mot de passe actuel"
msgid "New password"
msgstr "Nouveau mot de passe"
-#: lib/cannery_web/live/ammo_group_live/index.html.heex:72
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:93
#, elixir-autogen, elixir-format
msgid "Stage"
msgstr "Sélectionné"
-#: lib/cannery_web/live/ammo_group_live/index.html.heex:72
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:93
#, elixir-autogen, elixir-format
msgid "Unstage"
msgstr "Désélectionner"
@@ -844,7 +846,7 @@ msgstr ""
msgid "Container:"
msgstr "Conteneur"
-#: lib/cannery_web/live/ammo_group_live/index.html.heex:48
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:63
#: lib/cannery_web/live/ammo_type_live/index.html.heex:39
#: lib/cannery_web/live/ammo_type_live/show.html.heex:152
#: lib/cannery_web/live/container_live/show.html.heex:105
@@ -1107,7 +1109,7 @@ msgstr ""
msgid "Purchased on:"
msgstr ""
-#: lib/cannery_web/live/ammo_group_live/index.ex:38
+#: lib/cannery_web/live/ammo_group_live/index.ex:46
#, elixir-autogen, elixir-format, fuzzy
msgid "Edit ammo"
msgstr "Éditer le type de munition"
@@ -1122,3 +1124,8 @@ msgstr "Aucun type de munition"
#, elixir-autogen, elixir-format
msgid "Search catalog"
msgstr ""
+
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:57
+#, elixir-autogen, elixir-format, fuzzy
+msgid "Search ammo"
+msgstr ""
diff --git a/priv/gettext/fr/LC_MESSAGES/errors.po b/priv/gettext/fr/LC_MESSAGES/errors.po
index cdebc944..f40d5b06 100644
--- a/priv/gettext/fr/LC_MESSAGES/errors.po
+++ b/priv/gettext/fr/LC_MESSAGES/errors.po
@@ -186,7 +186,7 @@ msgstr "Impossible d'analyser le nombre de copies"
msgid "Invalid number of copies, must be between 1 and %{max}. Was %{multiplier}"
msgstr "Nombre de copies invalide, doit être 1 et %{max}. Été %{multiplier}"
-#: lib/cannery/ammo.ex:636
+#: lib/cannery/ammo.ex:686
#, elixir-autogen, elixir-format
msgid "Invalid multiplier"
msgstr "Multiplicateur invalide"
diff --git a/priv/gettext/fr/LC_MESSAGES/prompts.po b/priv/gettext/fr/LC_MESSAGES/prompts.po
index 2f53165e..3784336e 100644
--- a/priv/gettext/fr/LC_MESSAGES/prompts.po
+++ b/priv/gettext/fr/LC_MESSAGES/prompts.po
@@ -96,7 +96,7 @@ msgstr "Êtes-vous certain·e de supprimer %{name} ?"
msgid "Are you sure you want to delete the invite for %{name}?"
msgstr "Êtes-vous certain·e de supprimer l’invitation pour %{name} ?"
-#: lib/cannery_web/live/ammo_group_live/index.html.heex:131
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:152
#: lib/cannery_web/live/ammo_group_live/show.html.heex:75
#, elixir-autogen, elixir-format
msgid "Are you sure you want to delete this ammo?"
@@ -267,7 +267,7 @@ msgstr "Êtes-vous certain·e de vouloir changer votre langue ?"
msgid "Language updated successfully."
msgstr "Langue mise à jour avec succès."
-#: lib/cannery_web/live/ammo_group_live/index.ex:64
+#: lib/cannery_web/live/ammo_group_live/index.ex:89
#: lib/cannery_web/live/ammo_group_live/show.ex:55
#, elixir-autogen, elixir-format, fuzzy
msgid "Ammo deleted succesfully"
diff --git a/priv/gettext/ga/LC_MESSAGES/actions.po b/priv/gettext/ga/LC_MESSAGES/actions.po
index 1aabbe08..841b38b6 100644
--- a/priv/gettext/ga/LC_MESSAGES/actions.po
+++ b/priv/gettext/ga/LC_MESSAGES/actions.po
@@ -21,8 +21,8 @@ msgstr ""
## Run "mix gettext.extract" to bring this file up to
## date. Leave "msgstr"s empty as changing them here has no
## effect: edit them in PO (.po) files instead.
-#: lib/cannery_web/live/ammo_group_live/index.ex:44
-#: lib/cannery_web/live/ammo_group_live/index.ex:50
+#: lib/cannery_web/live/ammo_group_live/index.ex:54
+#: lib/cannery_web/live/ammo_group_live/index.ex:62
#: lib/cannery_web/live/ammo_group_live/index.html.heex:40
#, elixir-autogen, elixir-format
msgid "Add Ammo"
@@ -167,7 +167,7 @@ msgstr ""
msgid "Why not get some ready to shoot?"
msgstr ""
-#: lib/cannery_web/live/ammo_group_live/index.html.heex:79
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:100
#: lib/cannery_web/live/ammo_group_live/show.html.heex:101
#: lib/cannery_web/live/range_live/index.html.heex:38
#, elixir-autogen, elixir-format
diff --git a/priv/gettext/ga/LC_MESSAGES/default.po b/priv/gettext/ga/LC_MESSAGES/default.po
index 89d8d64f..370940c3 100644
--- a/priv/gettext/ga/LC_MESSAGES/default.po
+++ b/priv/gettext/ga/LC_MESSAGES/default.po
@@ -42,7 +42,8 @@ msgid "Admins:"
msgstr ""
#: lib/cannery_web/components/topbar.ex:73
-#: lib/cannery_web/live/ammo_group_live/index.ex:56
+#: lib/cannery_web/live/ammo_group_live/index.ex:70
+#: lib/cannery_web/live/ammo_group_live/index.ex:79
#: lib/cannery_web/live/ammo_group_live/index.html.heex:3
#: lib/cannery_web/live/range_live/index.ex:80
#, elixir-autogen, elixir-format
@@ -278,6 +279,7 @@ msgid "New Tag"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:8
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:70
#, elixir-autogen, elixir-format
msgid "No Ammo"
msgstr ""
@@ -485,7 +487,7 @@ msgid "No ammo staged"
msgstr ""
#: lib/cannery_web/components/add_shot_group_component.html.heex:3
-#: lib/cannery_web/live/ammo_group_live/index.ex:26
+#: lib/cannery_web/live/ammo_group_live/index.ex:30
#, elixir-autogen, elixir-format
msgid "Record shots"
msgstr ""
@@ -524,8 +526,8 @@ msgstr ""
msgid "Shot Records"
msgstr ""
-#: lib/cannery_web/live/ammo_group_live/index.ex:32
-#: lib/cannery_web/live/ammo_group_live/index.html.heex:96
+#: lib/cannery_web/live/ammo_group_live/index.ex:38
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:117
#, elixir-autogen, elixir-format
msgid "Move ammo"
msgstr ""
@@ -603,12 +605,12 @@ msgstr ""
msgid "New password"
msgstr ""
-#: lib/cannery_web/live/ammo_group_live/index.html.heex:72
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:93
#, elixir-autogen, elixir-format
msgid "Stage"
msgstr ""
-#: lib/cannery_web/live/ammo_group_live/index.html.heex:72
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:93
#, elixir-autogen, elixir-format
msgid "Unstage"
msgstr ""
@@ -835,7 +837,7 @@ msgstr ""
msgid "Container:"
msgstr ""
-#: lib/cannery_web/live/ammo_group_live/index.html.heex:48
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:63
#: lib/cannery_web/live/ammo_type_live/index.html.heex:39
#: lib/cannery_web/live/ammo_type_live/show.html.heex:152
#: lib/cannery_web/live/container_live/show.html.heex:105
@@ -1098,7 +1100,7 @@ msgstr ""
msgid "Purchased on:"
msgstr ""
-#: lib/cannery_web/live/ammo_group_live/index.ex:38
+#: lib/cannery_web/live/ammo_group_live/index.ex:46
#, elixir-autogen, elixir-format, fuzzy
msgid "Edit ammo"
msgstr ""
@@ -1113,3 +1115,8 @@ msgstr ""
#, elixir-autogen, elixir-format
msgid "Search catalog"
msgstr ""
+
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:57
+#, elixir-autogen, elixir-format, fuzzy
+msgid "Search ammo"
+msgstr ""
diff --git a/priv/gettext/ga/LC_MESSAGES/errors.po b/priv/gettext/ga/LC_MESSAGES/errors.po
index 7a03422c..50627d1f 100644
--- a/priv/gettext/ga/LC_MESSAGES/errors.po
+++ b/priv/gettext/ga/LC_MESSAGES/errors.po
@@ -185,7 +185,7 @@ msgstr ""
msgid "Invalid number of copies, must be between 1 and %{max}. Was %{multiplier}"
msgstr ""
-#: lib/cannery/ammo.ex:636
+#: lib/cannery/ammo.ex:686
#, elixir-autogen, elixir-format
msgid "Invalid multiplier"
msgstr ""
diff --git a/priv/gettext/ga/LC_MESSAGES/prompts.po b/priv/gettext/ga/LC_MESSAGES/prompts.po
index 3c08fd99..f3c4b5bd 100644
--- a/priv/gettext/ga/LC_MESSAGES/prompts.po
+++ b/priv/gettext/ga/LC_MESSAGES/prompts.po
@@ -91,7 +91,7 @@ msgstr ""
msgid "Are you sure you want to delete the invite for %{name}?"
msgstr ""
-#: lib/cannery_web/live/ammo_group_live/index.html.heex:131
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:152
#: lib/cannery_web/live/ammo_group_live/show.html.heex:75
#, elixir-autogen, elixir-format
msgid "Are you sure you want to delete this ammo?"
@@ -256,7 +256,7 @@ msgstr ""
msgid "Language updated successfully."
msgstr ""
-#: lib/cannery_web/live/ammo_group_live/index.ex:64
+#: lib/cannery_web/live/ammo_group_live/index.ex:89
#: lib/cannery_web/live/ammo_group_live/show.ex:55
#, elixir-autogen, elixir-format
msgid "Ammo deleted succesfully"
diff --git a/priv/gettext/prompts.pot b/priv/gettext/prompts.pot
index 10b425f9..e68a9f7c 100644
--- a/priv/gettext/prompts.pot
+++ b/priv/gettext/prompts.pot
@@ -80,7 +80,7 @@ msgstr ""
msgid "Are you sure you want to delete the invite for %{name}?"
msgstr ""
-#: lib/cannery_web/live/ammo_group_live/index.html.heex:131
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:152
#: lib/cannery_web/live/ammo_group_live/show.html.heex:75
#, elixir-autogen, elixir-format
msgid "Are you sure you want to delete this ammo?"
@@ -245,7 +245,7 @@ msgstr ""
msgid "Language updated successfully."
msgstr ""
-#: lib/cannery_web/live/ammo_group_live/index.ex:64
+#: lib/cannery_web/live/ammo_group_live/index.ex:89
#: lib/cannery_web/live/ammo_group_live/show.ex:55
#, elixir-autogen, elixir-format
msgid "Ammo deleted succesfully"
diff --git a/test/cannery/ammo_test.exs b/test/cannery/ammo_test.exs
index b2cc5cea..66425d63 100644
--- a/test/cannery/ammo_test.exs
+++ b/test/cannery/ammo_test.exs
@@ -4,7 +4,7 @@ defmodule Cannery.AmmoTest do
"""
use Cannery.DataCase
- alias Cannery.{Ammo, Ammo.AmmoGroup, Ammo.AmmoType}
+ alias Cannery.{Ammo, Ammo.AmmoGroup, Ammo.AmmoType, Containers}
alias Ecto.Changeset
@moduletag :ammo_test
@@ -294,6 +294,13 @@ defmodule Cannery.AmmoTest do
%{"count" => 50, "price_paid" => 36.1}
|> ammo_group_fixture(ammo_type, container, current_user)
+ another_user = user_fixture()
+ another_ammo_type = ammo_type_fixture(another_user)
+ another_container = container_fixture(another_user)
+
+ {1, [_shouldnt_show_up]} =
+ ammo_group_fixture(another_ammo_type, another_container, another_user)
+
[
ammo_type: ammo_type,
ammo_group: ammo_group,
@@ -302,7 +309,7 @@ defmodule Cannery.AmmoTest do
]
end
- test "list_ammo_groups/2 returns all ammo_groups",
+ test "list_ammo_groups/3 returns all ammo_groups",
%{
ammo_type: ammo_type,
ammo_group: ammo_group,
@@ -314,13 +321,65 @@ defmodule Cannery.AmmoTest do
shot_group_fixture(%{"count" => 30}, current_user, another_ammo_group)
another_ammo_group = another_ammo_group |> Repo.reload!()
- assert Ammo.list_ammo_groups(current_user) == [ammo_group] |> Repo.preload(:shot_groups)
- assert Ammo.list_ammo_groups(current_user, true)
+ assert Ammo.list_ammo_groups(nil, false, current_user) ==
+ [ammo_group] |> preload_ammo_group()
+
+ assert Ammo.list_ammo_groups(nil, true, current_user)
|> Enum.sort_by(fn %{count: count} -> count end) ==
- [another_ammo_group, ammo_group] |> Repo.preload(:shot_groups)
+ [another_ammo_group, ammo_group] |> preload_ammo_group()
end
+ test "list_ammo_groups/3 returns relevant ammo groups when searched",
+ %{
+ ammo_type: ammo_type,
+ ammo_group: ammo_group,
+ container: container,
+ current_user: current_user
+ } do
+ {1, [another_ammo_group]} =
+ %{"count" => 49, "notes" => "cool ammo group"}
+ |> ammo_group_fixture(ammo_type, container, current_user)
+
+ another_ammo_type = ammo_type_fixture(%{"name" => "amazing ammo"}, current_user)
+ another_container = container_fixture(%{"name" => "fantastic container"}, current_user)
+
+ tag = tag_fixture(%{"name" => "stupendous tag"}, current_user)
+ Containers.add_tag!(another_container, tag, current_user)
+
+ {1, [amazing_ammo_group]} =
+ ammo_group_fixture(%{"count" => 48}, another_ammo_type, container, current_user)
+
+ {1, [fantastic_ammo_group]} =
+ ammo_group_fixture(%{"count" => 47}, ammo_type, another_container, current_user)
+
+ assert Ammo.list_ammo_groups(nil, false, current_user)
+ |> Enum.sort_by(fn %{count: count} -> count end) ==
+ [fantastic_ammo_group, amazing_ammo_group, another_ammo_group, ammo_group]
+ |> preload_ammo_group()
+
+ # search works for ammo group attributes
+ assert Ammo.list_ammo_groups("cool", true, current_user) ==
+ [another_ammo_group] |> preload_ammo_group()
+
+ # search works for ammo type attributes
+ assert Ammo.list_ammo_groups("amazing", true, current_user) ==
+ [amazing_ammo_group] |> preload_ammo_group()
+
+ # search works for container attributes
+ assert Ammo.list_ammo_groups("fantastic", true, current_user) ==
+ [fantastic_ammo_group] |> preload_ammo_group()
+
+ # search works for container tag attributes
+ assert Ammo.list_ammo_groups("stupendous", true, current_user) ==
+ [fantastic_ammo_group] |> preload_ammo_group()
+
+ assert Ammo.list_ammo_groups("random", true, current_user) == []
+ end
+
+ defp preload_ammo_group(ammo_group),
+ do: ammo_group |> Repo.preload([:ammo_type, :shot_groups, container: :tags])
+
test "list_ammo_groups_for_type/2 returns all ammo_groups for a type",
%{
ammo_type: ammo_type,
diff --git a/test/cannery_web/live/ammo_group_live_test.exs b/test/cannery_web/live/ammo_group_live_test.exs
index f10c87ea..f8bb4cfa 100644
--- a/test/cannery_web/live/ammo_group_live_test.exs
+++ b/test/cannery_web/live/ammo_group_live_test.exs
@@ -66,6 +66,37 @@ defmodule CanneryWeb.AmmoGroupLiveTest do
assert html =~ ammo_group.ammo_type.name
end
+ test "can search for ammo_groups", %{conn: conn, ammo_group: ammo_group} do
+ {:ok, index_live, html} = live(conn, Routes.ammo_group_index_path(conn, :index))
+
+ ammo_group = ammo_group |> Repo.preload(:ammo_type)
+
+ assert html =~ ammo_group.ammo_type.name
+
+ assert index_live
+ |> form("[data-qa=\"ammo_group_search\"]",
+ search: %{search_term: ammo_group.ammo_type.name}
+ )
+ |> render_change() =~ ammo_group.ammo_type.name
+
+ assert_patch(
+ index_live,
+ Routes.ammo_group_index_path(conn, :search, ammo_group.ammo_type.name)
+ )
+
+ refute index_live
+ |> form("[data-qa=\"ammo_group_search\"]", search: %{search_term: "something_else"})
+ |> render_change() =~ ammo_group.ammo_type.name
+
+ assert_patch(index_live, Routes.ammo_group_index_path(conn, :search, "something_else"))
+
+ assert index_live
+ |> form("[data-qa=\"ammo_group_search\"]", search: %{search_term: ""})
+ |> render_change() =~ ammo_group.ammo_type.name
+
+ assert_patch(index_live, Routes.ammo_group_index_path(conn, :index))
+ end
+
test "saves a single new ammo_group", %{conn: conn} do
{:ok, index_live, _html} = live(conn, Routes.ammo_group_index_path(conn, :index))
@@ -111,7 +142,7 @@ defmodule CanneryWeb.AmmoGroupLiveTest do
|> follow_redirect(conn, Routes.ammo_group_index_path(conn, :index))
assert html =~ dgettext("prompts", "Ammo added successfully")
- assert Ammo.list_ammo_groups(current_user) |> Enum.count() == multiplier + 1
+ assert Ammo.list_ammo_groups(nil, false, current_user) |> Enum.count() == multiplier + 1
end
test "does not save invalid number of new ammo_groups", %{conn: conn} do