10 Commits

Author SHA1 Message Date
32801828fa fix shot records table disappearing after selecting an empty ammo class
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-30 20:08:37 -04:00
6ed3312ea8 add db migrations for ammo group to pack and ammo type class 2023-03-30 20:08:26 -04:00
b122253b9b improve tests 2023-03-30 20:08:20 -04:00
a68a16bf06 fix ammo type table not displaying class 2023-03-30 20:08:14 -04:00
4b6d0952f8 rename ammo groups to packs everywhere 2023-03-30 20:08:11 -04:00
0544b58ab6 rename ammo group files to pack 2023-03-30 20:07:28 -04:00
6d26103784 rename ammo groups to packs 2023-03-30 20:07:16 -04:00
0cae7c2940 rename ammo_type type to class
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-28 23:08:40 -04:00
1e645b5bb8 generate fonts with correct filename
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-28 22:03:14 -04:00
bab2b26c13 use atom keys in tests
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-28 21:57:29 -04:00
88 changed files with 3472 additions and 3401 deletions

View File

@ -1,3 +1,9 @@
# v0.9.1
- Rename ammo type's "type" to "class" to avoid confusion
- Fixes ammo type search
- Fixes shot records table disappearing after selecting an empty ammo class
- Code quality improvements
# v0.9.0
- Add length limits to all string fields
- Add selectable ammo types
@ -72,8 +78,8 @@
- Add shading to table component
- Fix chart to sum by day
- Fix whitespace when copying invite url
- Make ammo type show page also display ammo groups as table
- Make container show page also display ammo groups as table
- Make ammo type show page also display packs as table
- Make container show page also display packs as table
- Display CPR for ammo packs
- Add original count for ammo packs
- Add ammo pack CPR and original count to json export

View File

@ -17,8 +17,8 @@ If you're multilingual, this project can use your translations! Visit
functions as short as possible while keeping variable names descriptive! For
instance, use inline `do:` blocks for short functions and make your aliases as
short as possible without introducing ambiguity.
- I.e. since there's only one `AmmoGroup` in the app, please alias
`AmmoGroup.t()` instead of using `Cannery.Ammo.AmmoGroup.t()`
- I.e. since there's only one `Pack` in the app, please alias
`Pack.t()` instead of using `Cannery.Ammo.Pack.t()`
- Use pipelines when possible. If only calling a single method, a pipeline isn't
strictly necessary but still encouraged for future modification.
- Please add typespecs to your functions! Even your private functions may be

View File

@ -45,7 +45,7 @@ module.exports = (env, options) => {
{
test: /\.(woff(2)?|ttf|eot|svg|otf)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
type: 'asset/resource',
generator: { filename: 'fonts/[name][ext]' }
generator: { filename: 'fonts/[name].[ext]' }
}
]
},

View File

@ -4,7 +4,7 @@ defmodule Cannery.ActivityLog do
"""
import Ecto.Query, warn: false
alias Cannery.Ammo.{AmmoGroup, AmmoType}
alias Cannery.Ammo.{AmmoType, Pack}
alias Cannery.{Accounts.User, ActivityLog.ShotGroup, Repo}
alias Ecto.{Multi, Queryable}
@ -23,15 +23,15 @@ defmodule Cannery.ActivityLog do
[%ShotGroup{notes: "Shot some rifle rounds"}, ...]
"""
@spec list_shot_groups(AmmoType.type() | :all, User.t()) :: [ShotGroup.t()]
@spec list_shot_groups(search :: nil | String.t(), AmmoType.type() | :all, User.t()) ::
@spec list_shot_groups(AmmoType.class() | :all, User.t()) :: [ShotGroup.t()]
@spec list_shot_groups(search :: nil | String.t(), AmmoType.class() | :all, User.t()) ::
[ShotGroup.t()]
def list_shot_groups(search \\ nil, type, %{id: user_id}) do
from(sg in ShotGroup,
as: :sg,
left_join: ag in AmmoGroup,
left_join: ag in Pack,
as: :ag,
on: sg.ammo_group_id == ag.id,
on: sg.pack_id == ag.id,
left_join: at in AmmoType,
as: :at,
on: ag.ammo_type_id == at.id,
@ -79,27 +79,46 @@ defmodule Cannery.ActivityLog do
})
end
@spec list_shot_groups_filter_type(Queryable.t(), AmmoType.type() | :all) ::
@spec list_shot_groups_filter_type(Queryable.t(), AmmoType.class() | :all) ::
Queryable.t()
defp list_shot_groups_filter_type(query, :rifle),
do: query |> where([at: at], at.type == :rifle)
do: query |> where([at: at], at.class == :rifle)
defp list_shot_groups_filter_type(query, :pistol),
do: query |> where([at: at], at.type == :pistol)
do: query |> where([at: at], at.class == :pistol)
defp list_shot_groups_filter_type(query, :shotgun),
do: query |> where([at: at], at.type == :shotgun)
do: query |> where([at: at], at.class == :shotgun)
defp list_shot_groups_filter_type(query, _all), do: query
@spec list_shot_groups_for_ammo_group(AmmoGroup.t(), User.t()) :: [ShotGroup.t()]
def list_shot_groups_for_ammo_group(
%AmmoGroup{id: ammo_group_id, user_id: user_id},
@doc """
Returns a count of shot records.
## Examples
iex> get_shot_record_count!(%User{id: 123})
3
"""
@spec get_shot_record_count!(User.t()) :: integer()
def get_shot_record_count!(%User{id: user_id}) do
Repo.one(
from sg in ShotGroup,
where: sg.user_id == ^user_id,
select: count(sg.id),
distinct: true
) || 0
end
@spec list_shot_groups_for_pack(Pack.t(), User.t()) :: [ShotGroup.t()]
def list_shot_groups_for_pack(
%Pack{id: pack_id, user_id: user_id},
%User{id: user_id}
) do
Repo.all(
from sg in ShotGroup,
where: sg.ammo_group_id == ^ammo_group_id,
where: sg.pack_id == ^pack_id,
where: sg.user_id == ^user_id
)
end
@ -140,31 +159,31 @@ defmodule Cannery.ActivityLog do
{:error, %Ecto.Changeset{}}
"""
@spec create_shot_group(attrs :: map(), User.t(), AmmoGroup.t()) ::
@spec create_shot_group(attrs :: map(), User.t(), Pack.t()) ::
{:ok, ShotGroup.t()} | {:error, ShotGroup.changeset() | nil}
def create_shot_group(attrs, user, ammo_group) do
def create_shot_group(attrs, user, pack) do
Multi.new()
|> Multi.insert(
:create_shot_group,
%ShotGroup{} |> ShotGroup.create_changeset(user, ammo_group, attrs)
%ShotGroup{} |> ShotGroup.create_changeset(user, pack, attrs)
)
|> Multi.run(
:ammo_group,
fn _repo, %{create_shot_group: %{ammo_group_id: ammo_group_id, user_id: user_id}} ->
ammo_group =
:pack,
fn _repo, %{create_shot_group: %{pack_id: pack_id, user_id: user_id}} ->
pack =
Repo.one(
from ag in AmmoGroup,
where: ag.id == ^ammo_group_id,
from ag in Pack,
where: ag.id == ^pack_id,
where: ag.user_id == ^user_id
)
{:ok, ammo_group}
{:ok, pack}
end
)
|> Multi.update(
:update_ammo_group,
fn %{create_shot_group: %{count: shot_group_count}, ammo_group: %{count: ammo_group_count}} ->
ammo_group |> AmmoGroup.range_changeset(%{"count" => ammo_group_count - shot_group_count})
:update_pack,
fn %{create_shot_group: %{count: shot_group_count}, pack: %{count: pack_count}} ->
pack |> Pack.range_changeset(%{"count" => pack_count - shot_group_count})
end
)
|> Repo.transaction()
@ -200,21 +219,20 @@ defmodule Cannery.ActivityLog do
shot_group |> ShotGroup.update_changeset(user, attrs)
)
|> Multi.run(
:ammo_group,
fn repo, %{update_shot_group: %{ammo_group_id: ammo_group_id, user_id: user_id}} ->
{:ok,
repo.one(from ag in AmmoGroup, where: ag.id == ^ammo_group_id and ag.user_id == ^user_id)}
:pack,
fn repo, %{update_shot_group: %{pack_id: pack_id, user_id: user_id}} ->
{:ok, repo.one(from ag in Pack, where: ag.id == ^pack_id and ag.user_id == ^user_id)}
end
)
|> Multi.update(
:update_ammo_group,
:update_pack,
fn %{
update_shot_group: %{count: new_count},
ammo_group: %{count: ammo_group_count} = ammo_group
pack: %{count: pack_count} = pack
} ->
shot_diff_to_add = new_count - count
new_ammo_group_count = ammo_group_count - shot_diff_to_add
ammo_group |> AmmoGroup.range_changeset(%{"count" => new_ammo_group_count})
new_pack_count = pack_count - shot_diff_to_add
pack |> Pack.range_changeset(%{"count" => new_pack_count})
end
)
|> Repo.transaction()
@ -246,20 +264,19 @@ defmodule Cannery.ActivityLog do
Multi.new()
|> Multi.delete(:delete_shot_group, shot_group)
|> Multi.run(
:ammo_group,
fn repo, %{delete_shot_group: %{ammo_group_id: ammo_group_id, user_id: user_id}} ->
{:ok,
repo.one(from ag in AmmoGroup, where: ag.id == ^ammo_group_id and ag.user_id == ^user_id)}
:pack,
fn repo, %{delete_shot_group: %{pack_id: pack_id, user_id: user_id}} ->
{:ok, repo.one(from ag in Pack, where: ag.id == ^pack_id and ag.user_id == ^user_id)}
end
)
|> Multi.update(
:update_ammo_group,
:update_pack,
fn %{
delete_shot_group: %{count: count},
ammo_group: %{count: ammo_group_count} = ammo_group
pack: %{count: pack_count} = pack
} ->
new_ammo_group_count = ammo_group_count + count
ammo_group |> AmmoGroup.range_changeset(%{"count" => new_ammo_group_count})
new_pack_count = pack_count + count
pack |> Pack.range_changeset(%{"count" => new_pack_count})
end
)
|> Repo.transaction()
@ -271,60 +288,60 @@ defmodule Cannery.ActivityLog do
end
@doc """
Returns the number of shot rounds for an ammo group
Returns the number of shot rounds for a pack
"""
@spec get_used_count(AmmoGroup.t(), User.t()) :: non_neg_integer()
def get_used_count(%AmmoGroup{id: ammo_group_id} = ammo_group, user) do
[ammo_group]
@spec get_used_count(Pack.t(), User.t()) :: non_neg_integer()
def get_used_count(%Pack{id: pack_id} = pack, user) do
[pack]
|> get_used_counts(user)
|> Map.get(ammo_group_id, 0)
|> Map.get(pack_id, 0)
end
@doc """
Returns the number of shot rounds for multiple ammo groups
Returns the number of shot rounds for multiple packs
"""
@spec get_used_counts([AmmoGroup.t()], User.t()) ::
%{optional(AmmoGroup.id()) => non_neg_integer()}
def get_used_counts(ammo_groups, %User{id: user_id}) do
ammo_group_ids =
ammo_groups
|> Enum.map(fn %{id: ammo_group_id} -> ammo_group_id end)
@spec get_used_counts([Pack.t()], User.t()) ::
%{optional(Pack.id()) => non_neg_integer()}
def get_used_counts(packs, %User{id: user_id}) do
pack_ids =
packs
|> Enum.map(fn %{id: pack_id} -> pack_id end)
Repo.all(
from sg in ShotGroup,
where: sg.ammo_group_id in ^ammo_group_ids,
where: sg.pack_id in ^pack_ids,
where: sg.user_id == ^user_id,
group_by: sg.ammo_group_id,
select: {sg.ammo_group_id, sum(sg.count)}
group_by: sg.pack_id,
select: {sg.pack_id, sum(sg.count)}
)
|> Map.new()
end
@doc """
Returns the last entered shot group date for an ammo group
Returns the last entered shot group date for a pack
"""
@spec get_last_used_date(AmmoGroup.t(), User.t()) :: Date.t() | nil
def get_last_used_date(%AmmoGroup{id: ammo_group_id} = ammo_group, user) do
[ammo_group]
@spec get_last_used_date(Pack.t(), User.t()) :: Date.t() | nil
def get_last_used_date(%Pack{id: pack_id} = pack, user) do
[pack]
|> get_last_used_dates(user)
|> Map.get(ammo_group_id)
|> Map.get(pack_id)
end
@doc """
Returns the last entered shot group date for an ammo group
Returns the last entered shot group date for a pack
"""
@spec get_last_used_dates([AmmoGroup.t()], User.t()) :: %{optional(AmmoGroup.id()) => Date.t()}
def get_last_used_dates(ammo_groups, %User{id: user_id}) do
ammo_group_ids =
ammo_groups
|> Enum.map(fn %AmmoGroup{id: ammo_group_id, user_id: ^user_id} -> ammo_group_id end)
@spec get_last_used_dates([Pack.t()], User.t()) :: %{optional(Pack.id()) => Date.t()}
def get_last_used_dates(packs, %User{id: user_id}) do
pack_ids =
packs
|> Enum.map(fn %Pack{id: pack_id, user_id: ^user_id} -> pack_id end)
Repo.all(
from sg in ShotGroup,
where: sg.ammo_group_id in ^ammo_group_ids,
where: sg.pack_id in ^pack_ids,
where: sg.user_id == ^user_id,
group_by: sg.ammo_group_id,
select: {sg.ammo_group_id, max(sg.date)}
group_by: sg.pack_id,
select: {sg.pack_id, max(sg.date)}
)
|> Map.new()
end
@ -367,9 +384,9 @@ defmodule Cannery.ActivityLog do
|> Enum.map(fn %AmmoType{id: ammo_type_id, user_id: ^user_id} -> ammo_type_id end)
Repo.all(
from ag in AmmoGroup,
from ag in Pack,
left_join: sg in ShotGroup,
on: ag.id == sg.ammo_group_id,
on: ag.id == sg.pack_id,
where: ag.ammo_type_id in ^ammo_type_ids,
where: not (sg.count |> is_nil()),
group_by: ag.ammo_type_id,

View File

@ -6,7 +6,7 @@ defmodule Cannery.ActivityLog.ShotGroup do
use Ecto.Schema
import CanneryWeb.Gettext
import Ecto.Changeset
alias Cannery.{Accounts.User, Ammo, Ammo.AmmoGroup}
alias Cannery.{Accounts.User, Ammo, Ammo.Pack}
alias Ecto.{Changeset, UUID}
@derive {Jason.Encoder,
@ -15,7 +15,7 @@ defmodule Cannery.ActivityLog.ShotGroup do
:count,
:date,
:notes,
:ammo_group_id
:pack_id
]}
@primary_key {:id, :binary_id, autogenerate: true}
@foreign_key_type :binary_id
@ -25,7 +25,7 @@ defmodule Cannery.ActivityLog.ShotGroup do
field :notes, :string
field :user_id, :binary_id
field :ammo_group_id, :binary_id
field :pack_id, :binary_id
timestamps()
end
@ -35,7 +35,7 @@ defmodule Cannery.ActivityLog.ShotGroup do
count: integer,
notes: String.t() | nil,
date: Date.t() | nil,
ammo_group_id: AmmoGroup.id(),
pack_id: Pack.id(),
user_id: User.id(),
inserted_at: NaiveDateTime.t(),
updated_at: NaiveDateTime.t()
@ -48,46 +48,44 @@ defmodule Cannery.ActivityLog.ShotGroup do
@spec create_changeset(
new_shot_group(),
User.t() | any(),
AmmoGroup.t() | any(),
Pack.t() | any(),
attrs :: map()
) :: changeset()
def create_changeset(
shot_group,
%User{id: user_id},
%AmmoGroup{id: ammo_group_id, user_id: user_id} = ammo_group,
%Pack{id: pack_id, user_id: user_id} = pack,
attrs
) do
shot_group
|> change(user_id: user_id)
|> change(ammo_group_id: ammo_group_id)
|> change(pack_id: pack_id)
|> cast(attrs, [:count, :notes, :date])
|> validate_length(:notes, max: 255)
|> validate_create_shot_group_count(ammo_group)
|> validate_required([:date, :ammo_group_id, :user_id])
|> validate_create_shot_group_count(pack)
|> validate_required([:date, :pack_id, :user_id])
end
def create_changeset(shot_group, _invalid_user, _invalid_ammo_group, attrs) do
def create_changeset(shot_group, _invalid_user, _invalid_pack, attrs) do
shot_group
|> cast(attrs, [:count, :notes, :date])
|> validate_length(:notes, max: 255)
|> validate_required([:ammo_group_id, :user_id])
|> validate_required([:pack_id, :user_id])
|> add_error(:invalid, dgettext("errors", "Please select a valid user and ammo pack"))
end
defp validate_create_shot_group_count(changeset, %AmmoGroup{count: ammo_group_count}) do
defp validate_create_shot_group_count(changeset, %Pack{count: pack_count}) do
case changeset |> Changeset.get_field(:count) do
nil ->
changeset |> Changeset.add_error(:ammo_left, dgettext("errors", "can't be blank"))
count when count > ammo_group_count ->
count when count > pack_count ->
changeset
|> Changeset.add_error(:ammo_left, dgettext("errors", "Ammo left must be at least 0"))
count when count <= 0 ->
error =
dgettext("errors", "Ammo left can be at most %{count} rounds",
count: ammo_group_count - 1
)
dgettext("errors", "Ammo left can be at most %{count} rounds", count: pack_count - 1)
changeset |> Changeset.add_error(:ammo_left, error)
@ -109,17 +107,16 @@ defmodule Cannery.ActivityLog.ShotGroup do
defp validate_update_shot_group_count(
changeset,
%__MODULE__{ammo_group_id: ammo_group_id, count: count},
%__MODULE__{pack_id: pack_id, count: count},
user
) do
%{count: ammo_group_count} = Ammo.get_ammo_group!(ammo_group_id, user)
%{count: pack_count} = Ammo.get_pack!(pack_id, user)
new_shot_group_count = changeset |> Changeset.get_field(:count)
shot_diff_to_add = new_shot_group_count - count
if shot_diff_to_add > ammo_group_count do
error =
dgettext("errors", "Count can be at most %{count} shots", count: ammo_group_count + count)
if shot_diff_to_add > pack_count do
error = dgettext("errors", "Count can be at most %{count} shots", count: pack_count + count)
changeset |> Changeset.add_error(:count, error)
else

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@ defmodule Cannery.Ammo.AmmoType do
use Ecto.Schema
import Ecto.Changeset
alias Cannery.Accounts.User
alias Cannery.Ammo.AmmoGroup
alias Cannery.Ammo.Pack
alias Ecto.{Changeset, UUID}
@derive {Jason.Encoder,
@ -42,7 +42,7 @@ defmodule Cannery.Ammo.AmmoType do
field :name, :string
field :desc, :string
field :type, Ecto.Enum, values: [:rifle, :shotgun, :pistol]
field :class, Ecto.Enum, values: [:rifle, :shotgun, :pistol]
# common fields
# https://shootersreference.com/reloadingdata/bullet_abbreviations/
@ -83,7 +83,7 @@ defmodule Cannery.Ammo.AmmoType do
field :dram_equivalent, :string
field :user_id, :binary_id
has_many :ammo_groups, AmmoGroup
has_many :packs, Pack
timestamps()
end
@ -92,7 +92,7 @@ defmodule Cannery.Ammo.AmmoType do
id: id(),
name: String.t(),
desc: String.t() | nil,
type: type(),
class: class(),
bullet_type: String.t() | nil,
bullet_core: String.t() | nil,
cartridge: String.t() | nil,
@ -123,21 +123,21 @@ defmodule Cannery.Ammo.AmmoType do
manufacturer: String.t() | nil,
upc: String.t() | nil,
user_id: User.id(),
ammo_groups: [AmmoGroup.t()] | nil,
packs: [Pack.t()] | nil,
inserted_at: NaiveDateTime.t(),
updated_at: NaiveDateTime.t()
}
@type new_ammo_type :: %__MODULE__{}
@type id :: UUID.t()
@type changeset :: Changeset.t(t() | new_ammo_type())
@type type :: :rifle | :shotgun | :pistol | nil
@type class :: :rifle | :shotgun | :pistol | nil
@spec changeset_fields() :: [atom()]
defp changeset_fields,
do: [
:name,
:desc,
:type,
:class,
:bullet_type,
:bullet_core,
:cartridge,

View File

@ -1,4 +1,4 @@
defmodule Cannery.Ammo.AmmoGroup do
defmodule Cannery.Ammo.Pack do
@moduledoc """
A group of a certain ammunition type.
@ -25,7 +25,7 @@ defmodule Cannery.Ammo.AmmoGroup do
]}
@primary_key {:id, :binary_id, autogenerate: true}
@foreign_key_type :binary_id
schema "ammo_groups" do
schema "packs" do
field :count, :integer
field :notes, :string
field :price_paid, :float
@ -53,27 +53,27 @@ defmodule Cannery.Ammo.AmmoGroup do
inserted_at: NaiveDateTime.t(),
updated_at: NaiveDateTime.t()
}
@type new_ammo_group :: %__MODULE__{}
@type new_pack :: %__MODULE__{}
@type id :: UUID.t()
@type changeset :: Changeset.t(t() | new_ammo_group())
@type changeset :: Changeset.t(t() | new_pack())
@doc false
@spec create_changeset(
new_ammo_group(),
new_pack(),
AmmoType.t() | nil,
Container.t() | nil,
User.t(),
attrs :: map()
) :: changeset()
def create_changeset(
ammo_group,
pack,
%AmmoType{id: ammo_type_id},
%Container{id: container_id, user_id: user_id},
%User{id: user_id},
attrs
)
when is_binary(ammo_type_id) and is_binary(container_id) and is_binary(user_id) do
ammo_group
pack
|> change(ammo_type_id: ammo_type_id)
|> change(user_id: user_id)
|> change(container_id: container_id)
@ -85,17 +85,17 @@ defmodule Cannery.Ammo.AmmoGroup do
@doc """
Invalid changeset, used to prompt user to select ammo type and container
"""
def create_changeset(ammo_group, _invalid_ammo_type, _invalid_container, _invalid_user, attrs) do
ammo_group
def create_changeset(pack, _invalid_ammo_type, _invalid_container, _invalid_user, attrs) do
pack
|> cast(attrs, [:ammo_type_id, :container_id])
|> validate_required([:ammo_type_id, :container_id])
|> add_error(:invalid, dgettext("errors", "Please select an ammo type and container"))
end
@doc false
@spec update_changeset(t() | new_ammo_group(), attrs :: map(), User.t()) :: changeset()
def update_changeset(ammo_group, attrs, user) do
ammo_group
@spec update_changeset(t() | new_pack(), attrs :: map(), User.t()) :: changeset()
def update_changeset(pack, attrs, user) do
pack
|> cast(attrs, [:count, :price_paid, :notes, :staged, :purchased_on, :container_id])
|> validate_number(:count, greater_than_or_equal_to: 0)
|> validate_container_id(user)
@ -113,12 +113,12 @@ defmodule Cannery.Ammo.AmmoGroup do
end
@doc """
This range changeset is used when "using up" ammo groups, and allows for
This range changeset is used when "using up" packs, and allows for
updating the count to 0
"""
@spec range_changeset(t() | new_ammo_group(), attrs :: map()) :: changeset()
def range_changeset(ammo_group, attrs) do
ammo_group
@spec range_changeset(t() | new_pack(), attrs :: map()) :: changeset()
def range_changeset(pack, attrs) do
pack
|> cast(attrs, [:count, :staged])
|> validate_required([:count, :staged])
end

View File

@ -5,7 +5,7 @@ defmodule Cannery.Containers do
import CanneryWeb.Gettext
import Ecto.Query, warn: false
alias Cannery.{Accounts.User, Ammo.AmmoGroup, Repo}
alias Cannery.{Accounts.User, Ammo.Pack, Repo}
alias Cannery.Containers.{Container, ContainerTag, Tag}
alias Ecto.Changeset
@ -203,7 +203,7 @@ defmodule Cannery.Containers do
{:ok, Container.t()} | {:error, Container.changeset()}
def delete_container(%Container{user_id: user_id} = container, %User{id: user_id}) do
Repo.one(
from ag in AmmoGroup,
from ag in Pack,
where: ag.container_id == ^container.id,
select: count(ag.id)
)
@ -221,7 +221,7 @@ defmodule Cannery.Containers do
container
|> Container.update_changeset(%{})
|> Changeset.add_error(:ammo_groups, error)
|> Changeset.add_error(:packs, error)
|> Changeset.apply_action(:delete)
end
end

View File

@ -4,7 +4,7 @@ defmodule CanneryWeb.Components.AddShotGroupComponent do
"""
use CanneryWeb, :live_component
alias Cannery.{Accounts.User, ActivityLog, ActivityLog.ShotGroup, Ammo.AmmoGroup}
alias Cannery.{Accounts.User, ActivityLog, ActivityLog.ShotGroup, Ammo.Pack}
alias Ecto.Changeset
alias Phoenix.LiveView.{JS, Socket}
@ -12,15 +12,15 @@ defmodule CanneryWeb.Components.AddShotGroupComponent do
@spec update(
%{
required(:current_user) => User.t(),
required(:ammo_group) => AmmoGroup.t(),
required(:pack) => Pack.t(),
optional(any()) => any()
},
Socket.t()
) :: {:ok, Socket.t()}
def update(%{ammo_group: ammo_group, current_user: current_user} = assigns, socket) do
def update(%{pack: pack, current_user: current_user} = assigns, socket) do
changeset =
%ShotGroup{date: Date.utc_today()}
|> ShotGroup.create_changeset(current_user, ammo_group, %{})
|> ShotGroup.create_changeset(current_user, pack, %{})
{:ok, socket |> assign(assigns) |> assign(:changeset, changeset)}
end
@ -29,11 +29,11 @@ defmodule CanneryWeb.Components.AddShotGroupComponent do
def handle_event(
"validate",
%{"shot_group" => shot_group_params},
%{assigns: %{ammo_group: ammo_group, current_user: current_user}} = socket
%{assigns: %{pack: pack, current_user: current_user}} = socket
) do
params = shot_group_params |> process_params(ammo_group)
params = shot_group_params |> process_params(pack)
changeset = %ShotGroup{} |> ShotGroup.create_changeset(current_user, ammo_group, params)
changeset = %ShotGroup{} |> ShotGroup.create_changeset(current_user, pack, params)
changeset =
case changeset |> Changeset.apply_action(:validate) do
@ -48,13 +48,13 @@ defmodule CanneryWeb.Components.AddShotGroupComponent do
"save",
%{"shot_group" => shot_group_params},
%{
assigns: %{ammo_group: ammo_group, current_user: current_user, return_to: return_to}
assigns: %{pack: pack, current_user: current_user, return_to: return_to}
} = socket
) do
socket =
shot_group_params
|> process_params(ammo_group)
|> ActivityLog.create_shot_group(current_user, ammo_group)
|> process_params(pack)
|> ActivityLog.create_shot_group(current_user, pack)
|> case do
{:ok, _shot_group} ->
prompt = dgettext("prompts", "Shots recorded successfully")
@ -68,7 +68,7 @@ defmodule CanneryWeb.Components.AddShotGroupComponent do
end
# calculate count from shots left
defp process_params(params, %AmmoGroup{count: count}) do
defp process_params(params, %Pack{count: count}) do
shot_group_count =
if params |> Map.get("ammo_left", "") == "" do
nil

View File

@ -22,7 +22,7 @@
<%= label(f, :ammo_left, gettext("Rounds left"), class: "title text-lg text-primary-600") %>
<%= number_input(f, :ammo_left,
min: 0,
max: @ammo_group.count - 1,
max: @pack.count - 1,
placeholder: gettext("Rounds left"),
class: "input input-primary"
) %>

View File

@ -13,7 +13,7 @@ defmodule CanneryWeb.Components.AmmoTypeTableComponent do
%{
required(:id) => UUID.t(),
required(:current_user) => User.t(),
optional(:type) => AmmoType.type() | nil,
optional(:class) => AmmoType.class() | nil,
optional(:show_used) => boolean(),
optional(:ammo_types) => [AmmoType.t()],
optional(:actions) => Rendered.t(),
@ -26,7 +26,7 @@ defmodule CanneryWeb.Components.AmmoTypeTableComponent do
socket
|> assign(assigns)
|> assign_new(:show_used, fn -> false end)
|> assign_new(:type, fn -> :all end)
|> assign_new(:class, fn -> :all end)
|> assign_new(:actions, fn -> [] end)
|> display_ammo_types()
@ -39,7 +39,7 @@ defmodule CanneryWeb.Components.AmmoTypeTableComponent do
ammo_types: ammo_types,
current_user: current_user,
show_used: show_used,
type: type,
class: class,
actions: actions
}
} = socket
@ -48,7 +48,7 @@ defmodule CanneryWeb.Components.AmmoTypeTableComponent do
[
%{label: gettext("Cartridge"), key: :cartridge, type: :string},
%{
label: if(type == :shotgun, do: gettext("Gauge"), else: gettext("Caliber")),
label: if(class == :shotgun, do: gettext("Gauge"), else: gettext("Caliber")),
key: :caliber,
type: :string
},
@ -59,7 +59,7 @@ defmodule CanneryWeb.Components.AmmoTypeTableComponent do
%{label: gettext("Grains"), key: :grains, type: :string},
%{label: gettext("Bullet type"), key: :bullet_type, type: :string},
%{
label: if(type == :shotgun, do: gettext("Slug core"), else: gettext("Bullet core")),
label: if(class == :shotgun, do: gettext("Slug core"), else: gettext("Bullet core")),
key: :bullet_core,
type: :string
},
@ -147,13 +147,13 @@ defmodule CanneryWeb.Components.AmmoTypeTableComponent do
})
|> TableComponent.maybe_compose_columns(filtered_columns)
|> TableComponent.maybe_compose_columns(
%{label: gettext("Type"), key: :type, type: :atom},
type in [:all, nil]
%{label: gettext("Class"), key: :class, type: :atom},
class in [:all, nil]
)
|> TableComponent.maybe_compose_columns(%{label: gettext("Name"), key: :name, type: :name})
round_counts = ammo_types |> Ammo.get_round_count_for_ammo_types(current_user)
packs_count = ammo_types |> Ammo.get_ammo_groups_count_for_types(current_user)
packs_count = ammo_types |> Ammo.get_packs_count_for_types(current_user)
average_costs = ammo_types |> Ammo.get_average_cost_for_ammo_types(current_user)
[used_counts, historical_round_counts, historical_pack_counts, used_pack_counts] =
@ -161,8 +161,8 @@ defmodule CanneryWeb.Components.AmmoTypeTableComponent do
[
ammo_types |> ActivityLog.get_used_count_for_ammo_types(current_user),
ammo_types |> Ammo.get_historical_count_for_ammo_types(current_user),
ammo_types |> Ammo.get_ammo_groups_count_for_types(current_user, true),
ammo_types |> Ammo.get_used_ammo_groups_count_for_types(current_user)
ammo_types |> Ammo.get_packs_count_for_types(current_user, true),
ammo_types |> Ammo.get_used_packs_count_for_types(current_user)
]
else
[nil, nil, nil, nil]

View File

@ -71,7 +71,7 @@ defmodule CanneryWeb.Components.ContainerTableComponent do
current_user: current_user,
tag_actions: tag_actions,
actions: actions,
pack_count: Ammo.get_ammo_groups_count_for_containers(containers, current_user),
pack_count: Ammo.get_packs_count_for_containers(containers, current_user),
round_count: Ammo.get_round_count_for_containers(containers, current_user)
}

View File

@ -5,7 +5,7 @@ defmodule CanneryWeb.CoreComponents do
use Phoenix.Component
import CanneryWeb.{Gettext, ViewHelpers}
alias Cannery.{Accounts, Accounts.Invite, Accounts.User}
alias Cannery.{Ammo, Ammo.AmmoGroup}
alias Cannery.{Ammo, Ammo.Pack}
alias Cannery.{Containers.Container, Containers.Tag}
alias CanneryWeb.{Endpoint, HomeLive}
alias CanneryWeb.Router.Helpers, as: Routes
@ -86,7 +86,7 @@ defmodule CanneryWeb.CoreComponents do
def simple_tag_card(assigns)
attr :ammo_group, AmmoGroup, required: true
attr :pack, Pack, required: true
attr :current_user, User, required: true
attr :original_count, :integer, default: nil
attr :cpr, :integer, default: nil
@ -94,7 +94,7 @@ defmodule CanneryWeb.CoreComponents do
attr :container, Container, default: nil
slot(:inner_block)
def ammo_group_card(assigns)
def pack_card(assigns)
@spec display_currency(float()) :: String.t()
defp display_currency(float), do: :erlang.float_to_binary(float, decimals: 2)

View File

@ -27,10 +27,10 @@
<%= @container.location %>
</span>
<%= if @container |> Ammo.get_ammo_groups_count_for_container!(@current_user) != 0 do %>
<%= if @container |> Ammo.get_packs_count_for_container!(@current_user) != 0 do %>
<span class="rounded-lg title text-lg">
<%= gettext("Packs:") %>
<%= @container |> Ammo.get_ammo_groups_count_for_container!(@current_user) %>
<%= @container |> Ammo.get_packs_count_for_container!(@current_user) %>
</span>
<span class="rounded-lg title text-lg">

View File

@ -1,48 +1,45 @@
<div
id={"ammo_group-#{@ammo_group.id}"}
id={"pack-#{@pack.id}"}
class="mx-4 my-2 px-8 py-4
flex flex-col justify-center items-center
border border-gray-400 rounded-lg shadow-lg hover:shadow-md
transition-all duration-300 ease-in-out"
>
<.link navigate={Routes.ammo_group_show_path(Endpoint, :show, @ammo_group)} class="mb-2 link">
<.link navigate={Routes.pack_show_path(Endpoint, :show, @pack)} class="mb-2 link">
<h1 class="title text-xl title-primary-500">
<%= @ammo_group.ammo_type.name %>
<%= @pack.ammo_type.name %>
</h1>
</.link>
<div class="flex flex-col justify-center items-center">
<span class="rounded-lg title text-lg">
<%= gettext("Count:") %>
<%= if @ammo_group.count == 0, do: gettext("Empty"), else: @ammo_group.count %>
<%= if @pack.count == 0, do: gettext("Empty"), else: @pack.count %>
</span>
<span
:if={@original_count && @original_count != @ammo_group.count}
class="rounded-lg title text-lg"
>
<span :if={@original_count && @original_count != @pack.count} class="rounded-lg title text-lg">
<%= gettext("Original Count:") %>
<%= @original_count %>
</span>
<span :if={@ammo_group.notes} class="rounded-lg title text-lg">
<span :if={@pack.notes} class="rounded-lg title text-lg">
<%= gettext("Notes:") %>
<%= @ammo_group.notes %>
<%= @pack.notes %>
</span>
<span :if={@ammo_group.purchased_on} class="rounded-lg title text-lg">
<span :if={@pack.purchased_on} class="rounded-lg title text-lg">
<%= gettext("Purchased on:") %>
<.date id={"#{@ammo_group.id}-purchased-on"} date={@ammo_group.purchased_on} />
<.date id={"#{@pack.id}-purchased-on"} date={@pack.purchased_on} />
</span>
<span :if={@last_used_date} class="rounded-lg title text-lg">
<%= gettext("Last used on:") %>
<.date id={"#{@ammo_group.id}-last-used-on"} date={@last_used_date} />
<.date id={"#{@pack.id}-last-used-on"} date={@last_used_date} />
</span>
<span :if={@ammo_group.price_paid} class="rounded-lg title text-lg">
<span :if={@pack.price_paid} class="rounded-lg title text-lg">
<%= gettext("Price paid:") %>
<%= gettext("$%{amount}", amount: display_currency(@ammo_group.price_paid)) %>
<%= gettext("$%{amount}", amount: display_currency(@pack.price_paid)) %>
</span>
<span :if={@cpr} class="rounded-lg title text-lg">

View File

@ -52,7 +52,7 @@
</li>
<li class="mx-2 my-1">
<.link
navigate={Routes.ammo_group_index_path(Endpoint, :index)}
navigate={Routes.pack_index_path(Endpoint, :index)}
class="text-white hover:underline"
>
<%= gettext("Ammo") %>

View File

@ -1,10 +1,10 @@
defmodule CanneryWeb.Components.MoveAmmoGroupComponent do
defmodule CanneryWeb.Components.MovePackComponent do
@moduledoc """
Livecomponent that can move an ammo group to another container
Livecomponent that can move a pack to another container
"""
use CanneryWeb, :live_component
alias Cannery.{Accounts.User, Ammo, Ammo.AmmoGroup, Containers, Containers.Container}
alias Cannery.{Accounts.User, Ammo, Ammo.Pack, Containers, Containers.Container}
alias CanneryWeb.Endpoint
alias Ecto.Changeset
alias Phoenix.LiveView.Socket
@ -13,17 +13,16 @@ defmodule CanneryWeb.Components.MoveAmmoGroupComponent do
@spec update(
%{
required(:current_user) => User.t(),
required(:ammo_group) => AmmoGroup.t(),
required(:pack) => Pack.t(),
optional(any()) => any()
},
Socket.t()
) :: {:ok, Socket.t()}
def update(
%{ammo_group: %{container_id: container_id} = ammo_group, current_user: current_user} =
assigns,
%{pack: %{container_id: container_id} = pack, current_user: current_user} = assigns,
socket
) do
changeset = ammo_group |> AmmoGroup.update_changeset(%{}, current_user)
changeset = pack |> Pack.update_changeset(%{}, current_user)
containers =
Containers.list_containers(current_user)
@ -41,16 +40,15 @@ defmodule CanneryWeb.Components.MoveAmmoGroupComponent do
def handle_event(
"move",
%{"container_id" => container_id},
%{assigns: %{ammo_group: ammo_group, current_user: current_user, return_to: return_to}} =
socket
%{assigns: %{pack: pack, current_user: current_user, return_to: return_to}} = socket
) do
%{name: container_name} = Containers.get_container!(container_id, current_user)
socket =
ammo_group
|> Ammo.update_ammo_group(%{"container_id" => container_id}, current_user)
pack
|> Ammo.update_pack(%{"container_id" => container_id}, current_user)
|> case do
{:ok, _ammo_group} ->
{:ok, _pack} ->
prompt = dgettext("prompts", "Ammo moved to %{name} successfully", name: container_name)
socket |> put_flash(:info, prompt) |> push_navigate(to: return_to)
@ -92,7 +90,7 @@ defmodule CanneryWeb.Components.MoveAmmoGroupComponent do
<% else %>
<.live_component
module={CanneryWeb.Components.TableComponent}
id="move_ammo_group_table"
id="move_pack_table"
columns={@columns}
rows={@rows}
/>

View File

@ -1,9 +1,9 @@
defmodule CanneryWeb.Components.AmmoGroupTableComponent do
defmodule CanneryWeb.Components.PackTableComponent do
@moduledoc """
A component that displays a list of ammo groups
A component that displays a list of packs
"""
use CanneryWeb, :live_component
alias Cannery.{Accounts.User, Ammo.AmmoGroup, ComparableDate}
alias Cannery.{Accounts.User, Ammo.Pack, ComparableDate}
alias Cannery.{ActivityLog, Ammo, Containers}
alias CanneryWeb.Components.TableComponent
alias Ecto.UUID
@ -14,7 +14,7 @@ defmodule CanneryWeb.Components.AmmoGroupTableComponent do
%{
required(:id) => UUID.t(),
required(:current_user) => User.t(),
required(:ammo_groups) => [AmmoGroup.t()],
required(:packs) => [Pack.t()],
required(:show_used) => boolean(),
optional(:ammo_type) => Rendered.t(),
optional(:range) => Rendered.t(),
@ -25,8 +25,7 @@ defmodule CanneryWeb.Components.AmmoGroupTableComponent do
Socket.t()
) :: {:ok, Socket.t()}
def update(
%{id: _id, ammo_groups: _ammo_group, current_user: _current_user, show_used: _show_used} =
assigns,
%{id: _id, packs: _pack, current_user: _current_user, show_used: _show_used} = assigns,
socket
) do
socket =
@ -36,15 +35,15 @@ defmodule CanneryWeb.Components.AmmoGroupTableComponent do
|> assign_new(:range, fn -> [] end)
|> assign_new(:container, fn -> [] end)
|> assign_new(:actions, fn -> [] end)
|> display_ammo_groups()
|> display_packs()
{:ok, socket}
end
defp display_ammo_groups(
defp display_packs(
%{
assigns: %{
ammo_groups: ammo_groups,
packs: packs,
current_user: current_user,
ammo_type: ammo_type,
range: range,
@ -98,7 +97,7 @@ defmodule CanneryWeb.Components.AmmoGroupTableComponent do
)
containers =
ammo_groups
packs
|> Enum.map(fn %{container_id: container_id} -> container_id end)
|> Containers.get_containers(current_user)
@ -108,18 +107,18 @@ defmodule CanneryWeb.Components.AmmoGroupTableComponent do
columns: columns,
container: container,
containers: containers,
original_counts: Ammo.get_original_counts(ammo_groups, current_user),
cprs: Ammo.get_cprs(ammo_groups, current_user),
last_used_dates: ActivityLog.get_last_used_dates(ammo_groups, current_user),
percentages_remaining: Ammo.get_percentages_remaining(ammo_groups, current_user),
original_counts: Ammo.get_original_counts(packs, current_user),
cprs: Ammo.get_cprs(packs, current_user),
last_used_dates: ActivityLog.get_last_used_dates(packs, current_user),
percentages_remaining: Ammo.get_percentages_remaining(packs, current_user),
actions: actions,
range: range
}
rows =
ammo_groups
|> Enum.map(fn ammo_group ->
ammo_group |> get_row_data_for_ammo_group(extra_data)
packs
|> Enum.map(fn pack ->
pack |> get_row_data_for_pack(extra_data)
end)
socket |> assign(columns: columns, rows: rows)
@ -134,15 +133,15 @@ defmodule CanneryWeb.Components.AmmoGroupTableComponent do
"""
end
@spec get_row_data_for_ammo_group(AmmoGroup.t(), additional_data :: map()) :: map()
defp get_row_data_for_ammo_group(ammo_group, %{columns: columns} = additional_data) do
@spec get_row_data_for_pack(Pack.t(), additional_data :: map()) :: map()
defp get_row_data_for_pack(pack, %{columns: columns} = additional_data) do
columns
|> Map.new(fn %{key: key} ->
{key, get_value_for_key(key, ammo_group, additional_data)}
{key, get_value_for_key(key, pack, additional_data)}
end)
end
@spec get_value_for_key(atom(), AmmoGroup.t(), additional_data :: map()) ::
@spec get_value_for_key(atom(), Pack.t(), additional_data :: map()) ::
any() | {any(), Rendered.t()}
defp get_value_for_key(
:ammo_type,
@ -170,9 +169,9 @@ defmodule CanneryWeb.Components.AmmoGroupTableComponent do
"""}
end
defp get_value_for_key(:used_up_on, %{id: ammo_group_id}, %{last_used_dates: last_used_dates}) do
last_used_date = last_used_dates |> Map.get(ammo_group_id)
assigns = %{id: ammo_group_id, last_used_date: last_used_date}
defp get_value_for_key(:used_up_on, %{id: pack_id}, %{last_used_dates: last_used_dates}) do
last_used_date = last_used_dates |> Map.get(pack_id)
assigns = %{id: pack_id, last_used_date: last_used_date}
{last_used_date,
~H"""
@ -184,29 +183,29 @@ defmodule CanneryWeb.Components.AmmoGroupTableComponent do
"""}
end
defp get_value_for_key(:range, %{staged: staged} = ammo_group, %{range: range}) do
assigns = %{range: range, ammo_group: ammo_group}
defp get_value_for_key(:range, %{staged: staged} = pack, %{range: range}) do
assigns = %{range: range, pack: pack}
{staged,
~H"""
<%= render_slot(@range, @ammo_group) %>
<%= render_slot(@range, @pack) %>
"""}
end
defp get_value_for_key(
:remaining,
%{id: ammo_group_id},
%{id: pack_id},
%{percentages_remaining: percentages_remaining}
) do
percentage = Map.fetch!(percentages_remaining, ammo_group_id)
percentage = Map.fetch!(percentages_remaining, pack_id)
{percentage, gettext("%{percentage}%", percentage: percentage)}
end
defp get_value_for_key(:actions, ammo_group, %{actions: actions}) do
assigns = %{actions: actions, ammo_group: ammo_group}
defp get_value_for_key(:actions, pack, %{actions: actions}) do
assigns = %{actions: actions, pack: pack}
~H"""
<%= render_slot(@actions, @ammo_group) %>
<%= render_slot(@actions, @pack) %>
"""
end
@ -214,7 +213,7 @@ defmodule CanneryWeb.Components.AmmoGroupTableComponent do
defp get_value_for_key(
:container,
%{container_id: container_id} = ammo_group,
%{container_id: container_id} = pack,
%{container: container_block, containers: containers}
) do
container = %{name: container_name} = Map.fetch!(containers, container_id)
@ -222,35 +221,35 @@ defmodule CanneryWeb.Components.AmmoGroupTableComponent do
assigns = %{
container: container,
container_block: container_block,
ammo_group: ammo_group
pack: pack
}
{container_name,
~H"""
<%= render_slot(@container_block, {@ammo_group, @container}) %>
<%= render_slot(@container_block, {@pack, @container}) %>
"""}
end
defp get_value_for_key(
:original_count,
%{id: ammo_group_id},
%{id: pack_id},
%{original_counts: original_counts}
) do
Map.fetch!(original_counts, ammo_group_id)
Map.fetch!(original_counts, pack_id)
end
defp get_value_for_key(:cpr, %{price_paid: nil}, _additional_data),
do: {0, gettext("No cost information")}
defp get_value_for_key(:cpr, %{id: ammo_group_id}, %{cprs: cprs}) do
amount = Map.fetch!(cprs, ammo_group_id)
defp get_value_for_key(:cpr, %{id: pack_id}, %{cprs: cprs}) do
amount = Map.fetch!(cprs, pack_id)
{amount, gettext("$%{amount}", amount: display_currency(amount))}
end
defp get_value_for_key(:count, %{count: count}, _additional_data),
do: if(count == 0, do: {0, gettext("Empty")}, else: count)
defp get_value_for_key(key, ammo_group, _additional_data), do: ammo_group |> Map.get(key)
defp get_value_for_key(key, pack, _additional_data), do: pack |> Map.get(key)
@spec display_currency(float()) :: String.t()
defp display_currency(float), do: :erlang.float_to_binary(float, decimals: 2)

View File

@ -45,12 +45,12 @@ defmodule CanneryWeb.Components.ShotGroupTableComponent do
%{label: gettext("Actions"), key: :actions, sortable: false}
]
ammo_groups =
packs =
shot_groups
|> Enum.map(fn %{ammo_group_id: ammo_group_id} -> ammo_group_id end)
|> Ammo.get_ammo_groups(current_user)
|> Enum.map(fn %{pack_id: pack_id} -> pack_id end)
|> Ammo.get_packs(current_user)
extra_data = %{current_user: current_user, actions: actions, ammo_groups: ammo_groups}
extra_data = %{current_user: current_user, actions: actions, packs: packs}
rows =
shot_groups
@ -90,13 +90,13 @@ defmodule CanneryWeb.Components.ShotGroupTableComponent do
end)
end
defp get_row_value(:name, %{ammo_group_id: ammo_group_id}, %{ammo_groups: ammo_groups}) do
assigns = %{ammo_group: ammo_group = Map.fetch!(ammo_groups, ammo_group_id)}
defp get_row_value(:name, %{pack_id: pack_id}, %{packs: packs}) do
assigns = %{pack: pack = Map.fetch!(packs, pack_id)}
{ammo_group.ammo_type.name,
{pack.ammo_type.name,
~H"""
<.link navigate={Routes.ammo_group_show_path(Endpoint, :show, @ammo_group)} class="link">
<%= @ammo_group.ammo_type.name %>
<.link navigate={Routes.pack_show_path(Endpoint, :show, @pack)} class="link">
<%= @pack.ammo_type.name %>
</.link>
"""}
end

View File

@ -6,10 +6,9 @@ defmodule CanneryWeb.ExportController do
ammo_types = Ammo.list_ammo_types(current_user, :all)
used_counts = ammo_types |> ActivityLog.get_used_count_for_ammo_types(current_user)
round_counts = ammo_types |> Ammo.get_round_count_for_ammo_types(current_user)
ammo_group_counts = ammo_types |> Ammo.get_ammo_groups_count_for_types(current_user)
pack_counts = ammo_types |> Ammo.get_packs_count_for_types(current_user)
total_ammo_group_counts =
ammo_types |> Ammo.get_ammo_groups_count_for_types(current_user, true)
total_pack_counts = ammo_types |> Ammo.get_packs_count_for_types(current_user, true)
average_costs = ammo_types |> Ammo.get_average_cost_for_ammo_types(current_user)
@ -23,28 +22,28 @@ defmodule CanneryWeb.ExportController do
"average_cost" => Map.get(average_costs, ammo_type_id),
"round_count" => Map.get(round_counts, ammo_type_id, 0),
"used_count" => Map.get(used_counts, ammo_type_id, 0),
"ammo_group_count" => Map.get(ammo_group_counts, ammo_type_id, 0),
"total_ammo_group_count" => Map.get(total_ammo_group_counts, ammo_type_id, 0)
"pack_count" => Map.get(pack_counts, ammo_type_id, 0),
"total_pack_count" => Map.get(total_pack_counts, ammo_type_id, 0)
})
end)
ammo_groups = Ammo.list_ammo_groups(nil, :all, current_user, true)
used_counts = ammo_groups |> ActivityLog.get_used_counts(current_user)
original_counts = ammo_groups |> Ammo.get_original_counts(current_user)
cprs = ammo_groups |> Ammo.get_cprs(current_user)
percentages_remaining = ammo_groups |> Ammo.get_percentages_remaining(current_user)
packs = Ammo.list_packs(nil, :all, current_user, true)
used_counts = packs |> ActivityLog.get_used_counts(current_user)
original_counts = packs |> Ammo.get_original_counts(current_user)
cprs = packs |> Ammo.get_cprs(current_user)
percentages_remaining = packs |> Ammo.get_percentages_remaining(current_user)
ammo_groups =
ammo_groups
|> Enum.map(fn %{id: ammo_group_id} = ammo_group ->
ammo_group
packs =
packs
|> Enum.map(fn %{id: pack_id} = pack ->
pack
|> Jason.encode!()
|> Jason.decode!()
|> Map.merge(%{
"used_count" => Map.get(used_counts, ammo_group_id),
"percentage_remaining" => Map.fetch!(percentages_remaining, ammo_group_id),
"original_count" => Map.get(original_counts, ammo_group_id),
"cpr" => Map.get(cprs, ammo_group_id)
"used_count" => Map.get(used_counts, pack_id),
"percentage_remaining" => Map.fetch!(percentages_remaining, pack_id),
"original_count" => Map.get(original_counts, pack_id),
"cpr" => Map.get(cprs, pack_id)
})
end)
@ -53,14 +52,14 @@ defmodule CanneryWeb.ExportController do
containers =
Containers.list_containers(current_user)
|> Enum.map(fn container ->
ammo_group_count = container |> Ammo.get_ammo_groups_count_for_container!(current_user)
pack_count = container |> Ammo.get_packs_count_for_container!(current_user)
round_count = container |> Ammo.get_round_count_for_container!(current_user)
container
|> Jason.encode!()
|> Jason.decode!()
|> Map.merge(%{
"ammo_group_count" => ammo_group_count,
"pack_count" => pack_count,
"round_count" => round_count
})
end)
@ -68,7 +67,7 @@ defmodule CanneryWeb.ExportController do
json(conn, %{
user: current_user,
ammo_types: ammo_types,
ammo_groups: ammo_groups,
packs: packs,
shot_groups: shot_groups,
containers: containers
})

View File

@ -18,15 +18,15 @@
<%= dgettext("errors", "Oops, something went wrong! Please check the errors below.") %>
</div>
<%= label(f, :type, gettext("Type"), class: "title text-lg text-primary-600") %>
<%= label(f, :class, gettext("Class"), class: "title text-lg text-primary-600") %>
<%= select(
f,
:type,
:class,
[{gettext("Rifle"), :rifle}, {gettext("Shotgun"), :shotgun}, {gettext("Pistol"), :pistol}],
class: "text-center col-span-2 input input-primary",
maxlength: 255
) %>
<%= error_tag(f, :type, "col-span-3 text-center") %>
<%= error_tag(f, :class, "col-span-3 text-center") %>
<%= label(f, :name, gettext("Name"), class: "title text-lg text-primary-600") %>
<%= text_input(f, :name,
@ -48,7 +48,7 @@
<%= gettext("Dimensions") %>
</h2>
<%= if Changeset.get_field(@changeset, :type) in [:rifle, :pistol] do %>
<%= if Changeset.get_field(@changeset, :class) in [:rifle, :pistol] do %>
<%= label(f, :cartridge, gettext("Cartridge"), class: "title text-lg text-primary-600") %>
<%= text_input(f, :cartridge,
class: "text-center col-span-2 input input-primary",
@ -63,7 +63,7 @@
<%= label(
f,
:caliber,
if(Changeset.get_field(@changeset, :type) == :shotgun,
if(Changeset.get_field(@changeset, :class) == :shotgun,
do: gettext("Gauge"),
else: gettext("Caliber")
),
@ -76,7 +76,7 @@
) %>
<%= error_tag(f, :caliber, "col-span-3 text-center") %>
<%= if Changeset.get_field(@changeset, :type) == :shotgun do %>
<%= if Changeset.get_field(@changeset, :class) == :shotgun do %>
<%= label(f, :unfired_length, gettext("Unfired shell length"),
class: "title text-lg text-primary-600"
) %>
@ -139,7 +139,7 @@
<%= label(
f,
:bullet_core,
if(Changeset.get_field(@changeset, :type) == :shotgun,
if(Changeset.get_field(@changeset, :class) == :shotgun,
do: gettext("Slug core"),
else: gettext("Bullet core")
),
@ -152,7 +152,7 @@
) %>
<%= error_tag(f, :bullet_core, "col-span-3 text-center") %>
<%= if Changeset.get_field(@changeset, :type) in [:rifle, :pistol] do %>
<%= if Changeset.get_field(@changeset, :class) in [:rifle, :pistol] do %>
<%= label(f, :jacket_type, gettext("Jacket type"), class: "title text-lg text-primary-600") %>
<%= text_input(f, :jacket_type,
class: "text-center col-span-2 input input-primary",
@ -172,7 +172,7 @@
) %>
<%= error_tag(f, :case_material, "col-span-3 text-center") %>
<%= if Changeset.get_field(@changeset, :type) == :shotgun do %>
<%= if Changeset.get_field(@changeset, :class) == :shotgun do %>
<%= label(f, :wadding, gettext("Wadding"), class: "title text-lg text-primary-600") %>
<%= text_input(f, :wadding,
class: "text-center col-span-2 input input-primary",
@ -240,7 +240,7 @@
) %>
<%= error_tag(f, :powder_type, "col-span-3 text-center") %>
<%= if Changeset.get_field(@changeset, :type) in [:rifle, :pistol] do %>
<%= if Changeset.get_field(@changeset, :class) in [:rifle, :pistol] do %>
<%= label(f, :powder_grains_per_charge, gettext("Powder grains per charge"),
class: "title text-lg text-primary-600"
) %>
@ -262,7 +262,7 @@
) %>
<%= error_tag(f, :pressure, "col-span-3 text-center") %>
<%= if Changeset.get_field(@changeset, :type) == :shotgun do %>
<%= if Changeset.get_field(@changeset, :class) == :shotgun do %>
<%= label(f, :dram_equivalent, gettext("Dram equivalent"),
class: "title text-lg text-primary-600"
) %>
@ -275,7 +275,7 @@
<%= hidden_input(f, :dram_equivalent, value: nil) %>
<% end %>
<%= if Changeset.get_field(@changeset, :type) in [:rifle, :pistol] do %>
<%= if Changeset.get_field(@changeset, :class) in [:rifle, :pistol] do %>
<%= label(f, :muzzle_velocity, gettext("Muzzle velocity"),
class: "title text-lg text-primary-600"
) %>

View File

@ -8,11 +8,11 @@ defmodule CanneryWeb.AmmoTypeLive.Index do
@impl true
def mount(%{"search" => search}, _session, socket) do
{:ok, socket |> assign(type: :all, show_used: false, search: search) |> list_ammo_types()}
{:ok, socket |> assign(class: :all, show_used: false, search: search) |> list_ammo_types()}
end
def mount(_params, _session, socket) do
{:ok, socket |> assign(type: :all, show_used: false, search: nil) |> list_ammo_types()}
{:ok, socket |> assign(class: :all, show_used: false, search: nil) |> list_ammo_types()}
end
@impl true
@ -86,28 +86,28 @@ defmodule CanneryWeb.AmmoTypeLive.Index do
{:noreply, socket |> push_patch(to: search_path)}
end
def handle_event("change_type", %{"ammo_type" => %{"type" => "rifle"}}, socket) do
{:noreply, socket |> assign(:type, :rifle) |> list_ammo_types()}
def handle_event("change_class", %{"ammo_type" => %{"class" => "rifle"}}, socket) do
{:noreply, socket |> assign(:class, :rifle) |> list_ammo_types()}
end
def handle_event("change_type", %{"ammo_type" => %{"type" => "shotgun"}}, socket) do
{:noreply, socket |> assign(:type, :shotgun) |> list_ammo_types()}
def handle_event("change_class", %{"ammo_type" => %{"class" => "shotgun"}}, socket) do
{:noreply, socket |> assign(:class, :shotgun) |> list_ammo_types()}
end
def handle_event("change_type", %{"ammo_type" => %{"type" => "pistol"}}, socket) do
{:noreply, socket |> assign(:type, :pistol) |> list_ammo_types()}
def handle_event("change_class", %{"ammo_type" => %{"class" => "pistol"}}, socket) do
{:noreply, socket |> assign(:class, :pistol) |> list_ammo_types()}
end
def handle_event("change_type", %{"ammo_type" => %{"type" => _all}}, socket) do
{:noreply, socket |> assign(:type, :all) |> list_ammo_types()}
def handle_event("change_class", %{"ammo_type" => %{"class" => _all}}, socket) do
{:noreply, socket |> assign(:class, :all) |> list_ammo_types()}
end
defp list_ammo_types(
%{assigns: %{type: type, search: search, current_user: current_user}} = socket
%{assigns: %{class: class, search: search, current_user: current_user}} = socket
) do
socket
|> assign(
ammo_types: Ammo.list_ammo_types(search, current_user, type),
ammo_types: Ammo.list_ammo_types(search, current_user, class),
ammo_types_count: Ammo.get_ammo_types_count!(current_user)
)
end

View File

@ -22,15 +22,15 @@
:let={f}
for={%{}}
as={:ammo_type}
phx-change="change_type"
phx-submit="change_type"
phx-change="change_class"
phx-submit="change_class"
class="flex items-center"
>
<%= label(f, :type, gettext("Type"), class: "title text-primary-600 text-lg text-center") %>
<%= label(f, :class, gettext("Class"), class: "title text-primary-600 text-lg text-center") %>
<%= select(
f,
:type,
:class,
[
{gettext("All"), :all},
{gettext("Rifle"), :rifle},
@ -38,7 +38,7 @@
{gettext("Pistol"), :pistol}
],
class: "mx-2 my-1 min-w-md input input-primary",
value: @type
value: @class
) %>
</.form>
@ -79,7 +79,7 @@
ammo_types={@ammo_types}
current_user={@current_user}
show_used={@show_used}
type={@type}
class={@class}
>
<:actions :let={ammo_type}>
<div class="px-4 py-2 space-x-4 flex justify-center items-center">

View File

@ -55,7 +55,7 @@ defmodule CanneryWeb.AmmoTypeLive.Show do
ammo_type |> Map.get(field) != default_value
end)
ammo_groups = ammo_type |> Ammo.list_ammo_groups_for_type(current_user, show_used)
packs = ammo_type |> Ammo.list_packs_for_type(current_user, show_used)
[
original_counts,
@ -66,9 +66,9 @@ defmodule CanneryWeb.AmmoTypeLive.Show do
] =
if show_used do
[
ammo_groups |> Ammo.get_original_counts(current_user),
ammo_type |> Ammo.get_used_ammo_groups_count_for_type(current_user),
ammo_type |> Ammo.get_ammo_groups_count_for_type(current_user, true),
packs |> Ammo.get_original_counts(current_user),
ammo_type |> Ammo.get_used_packs_count_for_type(current_user),
ammo_type |> Ammo.get_packs_count_for_type(current_user, true),
ammo_type |> ActivityLog.get_used_count_for_ammo_type(current_user),
ammo_type |> Ammo.get_historical_count_for_ammo_type(current_user)
]
@ -83,7 +83,7 @@ defmodule CanneryWeb.AmmoTypeLive.Show do
end
containers =
ammo_groups
packs
|> Enum.map(fn %{container_id: container_id} -> container_id end)
|> Containers.get_containers(current_user)
@ -91,16 +91,16 @@ defmodule CanneryWeb.AmmoTypeLive.Show do
|> assign(
page_title: page_title,
ammo_type: ammo_type,
ammo_groups: ammo_groups,
packs: packs,
containers: containers,
cprs: ammo_groups |> Ammo.get_cprs(current_user),
last_used_dates: ammo_groups |> ActivityLog.get_last_used_dates(current_user),
cprs: packs |> Ammo.get_cprs(current_user),
last_used_dates: packs |> ActivityLog.get_last_used_dates(current_user),
avg_cost_per_round: ammo_type |> Ammo.get_average_cost_for_ammo_type(current_user),
rounds: ammo_type |> Ammo.get_round_count_for_ammo_type(current_user),
original_counts: original_counts,
used_rounds: used_rounds,
historical_round_count: historical_round_count,
packs_count: ammo_type |> Ammo.get_ammo_groups_count_for_type(current_user),
packs_count: ammo_type |> Ammo.get_packs_count_for_type(current_user),
used_packs_count: used_packs_count,
historical_packs_count: historical_packs_count,
fields_to_display: fields_to_display(ammo_type),
@ -116,11 +116,11 @@ defmodule CanneryWeb.AmmoTypeLive.Show do
socket |> display_ammo_type(ammo_type)
end
defp fields_to_display(%AmmoType{type: type}) do
defp fields_to_display(%AmmoType{class: class}) do
[
%{label: gettext("Cartridge:"), key: :cartridge, type: :string},
%{
label: if(type == :shotgun, do: gettext("Gauge:"), else: gettext("Caliber:")),
label: if(class == :shotgun, do: gettext("Gauge:"), else: gettext("Caliber:")),
key: :caliber,
type: :string
},

View File

@ -42,14 +42,14 @@
<hr class="hr" />
<%= if @ammo_type.type || @custom_fields? do %>
<%= if @ammo_type.class || @custom_fields? do %>
<div class="grid sm:grid-cols-2 gap-4 text-center justify-center items-center">
<h3 class="title text-lg">
<%= gettext("Type") %>
<%= gettext("Class") %>
</h3>
<span class="text-primary-600">
<%= case @ammo_type.type do %>
<%= case @ammo_type.class do %>
<% :shotgun -> %>
<%= gettext("Shotgun") %>
<% :rifle -> %>
@ -175,7 +175,7 @@
</div>
<div class="w-full p-4">
<%= if @ammo_groups |> Enum.empty?() do %>
<%= if @packs |> Enum.empty?() do %>
<h2 class="px-4 title text-lg text-primary-600">
<%= gettext("No ammo for this type") %>
<%= display_emoji("😔") %>
@ -183,13 +183,13 @@
<% else %>
<%= if @view_table do %>
<.live_component
module={CanneryWeb.Components.AmmoGroupTableComponent}
module={CanneryWeb.Components.PackTableComponent}
id="ammo-type-show-table"
ammo_groups={@ammo_groups}
packs={@packs}
current_user={@current_user}
show_used={@show_used}
>
<:container :let={{_ammo_group, %{name: container_name} = container}}>
<:container :let={{_pack, %{name: container_name} = container}}>
<.link
navigate={Routes.container_show_path(Endpoint, :show, container)}
class="mx-2 my-1 link"
@ -197,15 +197,13 @@
<%= container_name %>
</.link>
</:container>
<:actions :let={%{count: ammo_group_count} = ammo_group}>
<:actions :let={%{count: pack_count} = pack}>
<div class="py-2 px-4 h-full space-x-4 flex justify-center items-center">
<.link
navigate={Routes.ammo_group_show_path(Endpoint, :show, ammo_group)}
navigate={Routes.pack_show_path(Endpoint, :show, pack)}
class="text-primary-600 link"
aria-label={
dgettext("actions", "View ammo group of %{ammo_group_count} bullets",
ammo_group_count: ammo_group_count
)
dgettext("actions", "View pack of %{pack_count} bullets", pack_count: pack_count)
}
>
<i class="fa-fw fa-lg fas fa-eye"></i>
@ -215,12 +213,12 @@
</.live_component>
<% else %>
<div class="flex flex-wrap justify-center items-stretch">
<.ammo_group_card
:for={%{id: ammo_group_id, container_id: container_id} = ammo_group <- @ammo_groups}
ammo_group={ammo_group}
original_count={@original_counts && Map.fetch!(@original_counts, ammo_group_id)}
cpr={Map.get(@cprs, ammo_group_id)}
last_used_date={Map.get(@last_used_dates, ammo_group_id)}
<.pack_card
:for={%{id: pack_id, container_id: container_id} = pack <- @packs}
pack={pack}
original_count={@original_counts && Map.fetch!(@original_counts, pack_id)}
cpr={Map.get(@cprs, pack_id)}
last_used_date={Map.get(@last_used_dates, pack_id)}
current_user={@current_user}
container={Map.fetch!(@containers, container_id)}
/>

View File

@ -79,15 +79,15 @@ defmodule CanneryWeb.ContainerLive.Index do
prompt = dgettext("prompts", "%{name} has been deleted", name: container_name)
socket |> put_flash(:info, prompt) |> display_containers()
{:error, %{action: :delete, errors: [ammo_groups: _error], valid?: false} = changeset} ->
ammo_groups_error = changeset |> changeset_errors(:ammo_groups) |> Enum.join(", ")
{:error, %{action: :delete, errors: [packs: _error], valid?: false} = changeset} ->
packs_error = changeset |> changeset_errors(:packs) |> Enum.join(", ")
prompt =
dgettext(
"errors",
"Could not delete %{name}: %{error}",
name: changeset |> Changeset.get_field(:name, "container"),
error: ammo_groups_error
error: packs_error
)
socket |> put_flash(:error, prompt)

View File

@ -11,13 +11,13 @@ defmodule CanneryWeb.ContainerLive.Show do
@impl true
def mount(_params, _session, socket),
do: {:ok, socket |> assign(type: :all, view_table: true)}
do: {:ok, socket |> assign(class: :all, view_table: true)}
@impl true
def handle_params(%{"id" => id}, _session, %{assigns: %{current_user: current_user}} = socket) do
socket =
socket
|> assign(view_table: true)
|> assign(:view_table, true)
|> render_container(id, current_user)
{:noreply, socket}
@ -64,13 +64,13 @@ defmodule CanneryWeb.ContainerLive.Show do
|> put_flash(:info, prompt)
|> push_navigate(to: Routes.container_index_path(socket, :index))
{:error, %{action: :delete, errors: [ammo_groups: _error], valid?: false} = changeset} ->
ammo_groups_error = changeset |> changeset_errors(:ammo_groups) |> Enum.join(", ")
{:error, %{action: :delete, errors: [packs: _error], valid?: false} = changeset} ->
packs_error = changeset |> changeset_errors(:packs) |> Enum.join(", ")
prompt =
dgettext("errors", "Could not delete %{name}: %{error}",
name: changeset |> Changeset.get_field(:name, "container"),
error: ammo_groups_error
error: packs_error
)
socket |> put_flash(:error, prompt)
@ -86,33 +86,33 @@ defmodule CanneryWeb.ContainerLive.Show do
{:noreply, socket |> assign(:view_table, !view_table) |> render_container()}
end
def handle_event("change_type", %{"ammo_type" => %{"type" => "rifle"}}, socket) do
{:noreply, socket |> assign(:type, :rifle) |> render_container()}
def handle_event("change_class", %{"ammo_type" => %{"class" => "rifle"}}, socket) do
{:noreply, socket |> assign(:class, :rifle) |> render_container()}
end
def handle_event("change_type", %{"ammo_type" => %{"type" => "shotgun"}}, socket) do
{:noreply, socket |> assign(:type, :shotgun) |> render_container()}
def handle_event("change_class", %{"ammo_type" => %{"class" => "shotgun"}}, socket) do
{:noreply, socket |> assign(:class, :shotgun) |> render_container()}
end
def handle_event("change_type", %{"ammo_type" => %{"type" => "pistol"}}, socket) do
{:noreply, socket |> assign(:type, :pistol) |> render_container()}
def handle_event("change_class", %{"ammo_type" => %{"class" => "pistol"}}, socket) do
{:noreply, socket |> assign(:class, :pistol) |> render_container()}
end
def handle_event("change_type", %{"ammo_type" => %{"type" => _all}}, socket) do
{:noreply, socket |> assign(:type, :all) |> render_container()}
def handle_event("change_class", %{"ammo_type" => %{"class" => _all}}, socket) do
{:noreply, socket |> assign(:class, :all) |> render_container()}
end
@spec render_container(Socket.t(), Container.id(), User.t()) :: Socket.t()
defp render_container(
%{assigns: %{type: type, live_action: live_action}} = socket,
%{assigns: %{class: class, live_action: live_action}} = socket,
id,
current_user
) do
%{name: container_name} = container = Containers.get_container!(id, current_user)
ammo_groups = Ammo.list_ammo_groups_for_container(container, type, current_user)
original_counts = ammo_groups |> Ammo.get_original_counts(current_user)
cprs = ammo_groups |> Ammo.get_cprs(current_user)
last_used_dates = ammo_groups |> ActivityLog.get_last_used_dates(current_user)
packs = Ammo.list_packs_for_container(container, class, current_user)
original_counts = packs |> Ammo.get_original_counts(current_user)
cprs = packs |> Ammo.get_cprs(current_user)
last_used_dates = packs |> ActivityLog.get_last_used_dates(current_user)
page_title =
case live_action do
@ -125,8 +125,8 @@ defmodule CanneryWeb.ContainerLive.Show do
|> assign(
container: container,
round_count: Ammo.get_round_count_for_container!(container, current_user),
ammo_groups_count: Ammo.get_ammo_groups_count_for_container!(container, current_user),
ammo_groups: ammo_groups,
packs_count: Ammo.get_packs_count_for_container!(container, current_user),
packs: packs,
original_counts: original_counts,
cprs: cprs,
last_used_dates: last_used_dates,

View File

@ -20,7 +20,7 @@
<span class="rounded-lg title text-lg">
<%= gettext("Packs:") %>
<%= @ammo_groups_count %>
<%= @packs_count %>
</span>
<span class="rounded-lg title text-lg">
@ -90,15 +90,15 @@
:let={f}
for={%{}}
as={:ammo_type}
phx-change="change_type"
phx-submit="change_type"
phx-change="change_class"
phx-submit="change_class"
class="flex items-center"
>
<%= label(f, :type, gettext("Type"), class: "title text-primary-600 text-lg text-center") %>
<%= label(f, :class, gettext("Class"), class: "title text-primary-600 text-lg text-center") %>
<%= select(
f,
:type,
:class,
[
{gettext("All"), :all},
{gettext("Rifle"), :rifle},
@ -106,7 +106,7 @@
{gettext("Pistol"), :pistol}
],
class: "mx-2 my-1 min-w-md input input-primary",
value: @type
value: @class
) %>
</.form>
@ -118,16 +118,16 @@
</div>
<div class="w-full p-4">
<%= if @ammo_groups |> Enum.empty?() do %>
<%= if @packs |> Enum.empty?() do %>
<h2 class="mx-4 title text-lg text-primary-600 text-center">
<%= gettext("No ammo in this container") %>
</h2>
<% else %>
<%= if @view_table do %>
<.live_component
module={CanneryWeb.Components.AmmoGroupTableComponent}
module={CanneryWeb.Components.PackTableComponent}
id="ammo-type-show-table"
ammo_groups={@ammo_groups}
packs={@packs}
current_user={@current_user}
show_used={false}
>
@ -139,12 +139,12 @@
</.live_component>
<% else %>
<div class="flex flex-wrap justify-center items-stretch">
<.ammo_group_card
:for={%{id: ammo_group_id} = ammo_group <- @ammo_groups}
ammo_group={ammo_group}
original_count={Map.fetch!(@original_counts, ammo_group_id)}
cpr={Map.get(@cprs, ammo_group_id)}
last_used_date={Map.get(@last_used_dates, ammo_group_id)}
<.pack_card
:for={%{id: pack_id} = pack <- @packs}
pack={pack}
original_count={Map.fetch!(@original_counts, pack_id)}
cpr={Map.get(@cprs, pack_id)}
last_used_date={Map.get(@last_used_dates, pack_id)}
current_user={@current_user}
/>
</div>

View File

@ -1,22 +1,22 @@
defmodule CanneryWeb.AmmoGroupLive.FormComponent do
defmodule CanneryWeb.PackLive.FormComponent do
@moduledoc """
Livecomponent that can update or create an Cannery.Ammo.AmmoGroup
Livecomponent that can update or create an Cannery.Ammo.Pack
"""
use CanneryWeb, :live_component
alias Cannery.Ammo.{AmmoGroup, AmmoType}
alias Cannery.Ammo.{AmmoType, Pack}
alias Cannery.{Accounts.User, Ammo, Containers, Containers.Container}
alias Ecto.Changeset
alias Phoenix.LiveView.Socket
@ammo_group_create_limit 10_000
@pack_create_limit 10_000
@impl true
@spec update(
%{:ammo_group => AmmoGroup.t(), :current_user => User.t(), optional(any) => any},
%{:pack => Pack.t(), :current_user => User.t(), optional(any) => any},
Socket.t()
) :: {:ok, Socket.t()}
def update(%{ammo_group: _ammo_group} = assigns, socket) do
def update(%{pack: _pack} = assigns, socket) do
socket |> assign(assigns) |> update()
end
@ -25,7 +25,7 @@ defmodule CanneryWeb.AmmoGroupLive.FormComponent do
%{assigns: %{ammo_types: ammo_types, containers: containers}} =
socket =
socket
|> assign(:ammo_group_create_limit, @ammo_group_create_limit)
|> assign(:pack_create_limit, @pack_create_limit)
|> assign(:ammo_types, Ammo.list_ammo_types(current_user, :all))
|> assign_new(:containers, fn -> Containers.list_containers(current_user) end)
@ -43,16 +43,16 @@ defmodule CanneryWeb.AmmoGroupLive.FormComponent do
end
@impl true
def handle_event("validate", %{"ammo_group" => ammo_group_params}, socket) do
{:noreply, socket |> assign_changeset(ammo_group_params, :validate)}
def handle_event("validate", %{"pack" => pack_params}, socket) do
{:noreply, socket |> assign_changeset(pack_params, :validate)}
end
def handle_event(
"save",
%{"ammo_group" => ammo_group_params},
%{"pack" => pack_params},
%{assigns: %{action: action}} = socket
) do
save_ammo_group(socket, action, ammo_group_params)
save_pack(socket, action, pack_params)
end
# HTML Helpers
@ -70,8 +70,8 @@ defmodule CanneryWeb.AmmoGroupLive.FormComponent do
# Save Helpers
defp assign_changeset(
%{assigns: %{action: action, ammo_group: ammo_group, current_user: user}} = socket,
ammo_group_params,
%{assigns: %{action: action, pack: pack, current_user: user}} = socket,
pack_params,
changeset_action \\ nil
) do
default_action =
@ -83,12 +83,12 @@ defmodule CanneryWeb.AmmoGroupLive.FormComponent do
changeset =
case default_action do
:insert ->
ammo_type = maybe_get_ammo_type(ammo_group_params, user)
container = maybe_get_container(ammo_group_params, user)
ammo_group |> AmmoGroup.create_changeset(ammo_type, container, user, ammo_group_params)
ammo_type = maybe_get_ammo_type(pack_params, user)
container = maybe_get_container(pack_params, user)
pack |> Pack.create_changeset(ammo_type, container, user, pack_params)
:update ->
ammo_group |> AmmoGroup.update_changeset(ammo_group_params, user)
pack |> Pack.update_changeset(pack_params, user)
end
changeset =
@ -114,15 +114,14 @@ defmodule CanneryWeb.AmmoGroupLive.FormComponent do
defp maybe_get_ammo_type(_params_not_found, _user), do: nil
defp save_ammo_group(
%{assigns: %{ammo_group: ammo_group, current_user: current_user, return_to: return_to}} =
socket,
defp save_pack(
%{assigns: %{pack: pack, current_user: current_user, return_to: return_to}} = socket,
:edit,
ammo_group_params
pack_params
) do
socket =
case Ammo.update_ammo_group(ammo_group, ammo_group_params, current_user) do
{:ok, _ammo_group} ->
case Ammo.update_pack(pack, pack_params, current_user) do
{:ok, _pack} ->
prompt = dgettext("prompts", "Ammo updated successfully")
socket |> put_flash(:info, prompt) |> push_navigate(to: return_to)
@ -133,24 +132,24 @@ defmodule CanneryWeb.AmmoGroupLive.FormComponent do
{:noreply, socket}
end
defp save_ammo_group(
defp save_pack(
%{assigns: %{changeset: changeset}} = socket,
action,
%{"multiplier" => multiplier_str} = ammo_group_params
%{"multiplier" => multiplier_str} = pack_params
)
when action in [:new, :clone] do
socket =
case multiplier_str |> Integer.parse() do
{multiplier, _remainder}
when multiplier >= 1 and multiplier <= @ammo_group_create_limit ->
socket |> create_multiple(ammo_group_params, multiplier)
when multiplier >= 1 and multiplier <= @pack_create_limit ->
socket |> create_multiple(pack_params, multiplier)
{multiplier, _remainder} ->
error_msg =
dgettext(
"errors",
"Invalid number of copies, must be between 1 and %{max}. Was %{multiplier}",
max: @ammo_group_create_limit,
max: @pack_create_limit,
multiplier: multiplier
)
@ -176,11 +175,11 @@ defmodule CanneryWeb.AmmoGroupLive.FormComponent do
defp create_multiple(
%{assigns: %{current_user: current_user, return_to: return_to}} = socket,
ammo_group_params,
pack_params,
multiplier
) do
case Ammo.create_ammo_groups(ammo_group_params, multiplier, current_user) do
{:ok, {count, _ammo_groups}} ->
case Ammo.create_packs(pack_params, multiplier, current_user) do
{:ok, {count, _packs}} ->
prompt =
dngettext(
"prompts",

View File

@ -6,7 +6,7 @@
<.form
:let={f}
for={@changeset}
id="ammo_group-form"
id="pack-form"
phx-target={@myself}
phx-change="validate"
phx-submit="save"
@ -68,7 +68,7 @@
<%= label(f, :multiplier, gettext("Copies"), class: "title text-lg text-primary-600") %>
<%= number_input(f, :multiplier,
max: @ammo_group_create_limit,
max: @pack_create_limit,
class: "text-center input input-primary",
value: 1,
phx_update: "ignore"

View File

@ -1,23 +1,28 @@
defmodule CanneryWeb.AmmoGroupLive.Index do
defmodule CanneryWeb.PackLive.Index do
@moduledoc """
Liveview to show a Cannery.Ammo.AmmoGroup index
Liveview to show a Cannery.Ammo.Pack index
"""
use CanneryWeb, :live_view
alias Cannery.{Ammo, Ammo.AmmoGroup, Containers}
alias Cannery.{Ammo, Ammo.Pack, Containers}
@impl true
def mount(%{"search" => search}, _session, socket) do
{:ok, socket |> assign(type: :all, show_used: false, search: search) |> display_ammo_groups()}
socket =
socket
|> assign(class: :all, show_used: false, search: search)
|> display_packs()
{:ok, socket}
end
def mount(_params, _session, socket) do
{:ok, socket |> assign(type: :all, show_used: false, search: nil) |> display_ammo_groups()}
{:ok, socket |> assign(class: :all, show_used: false, search: nil) |> display_packs()}
end
@impl true
def handle_params(params, _url, %{assigns: %{live_action: live_action}} = socket) do
{:noreply, apply_action(socket, live_action, params) |> display_ammo_groups()}
{:noreply, apply_action(socket, live_action, params) |> display_packs()}
end
defp apply_action(
@ -28,7 +33,7 @@ defmodule CanneryWeb.AmmoGroupLive.Index do
socket
|> assign(
page_title: gettext("Record shots"),
ammo_group: Ammo.get_ammo_group!(id, current_user)
pack: Ammo.get_pack!(id, current_user)
)
end
@ -36,7 +41,7 @@ defmodule CanneryWeb.AmmoGroupLive.Index do
socket
|> assign(
page_title: gettext("Move ammo"),
ammo_group: Ammo.get_ammo_group!(id, current_user)
pack: Ammo.get_pack!(id, current_user)
)
end
@ -44,7 +49,7 @@ defmodule CanneryWeb.AmmoGroupLive.Index do
socket
|> assign(
page_title: gettext("Edit ammo"),
ammo_group: Ammo.get_ammo_group!(id, current_user)
pack: Ammo.get_pack!(id, current_user)
)
end
@ -52,7 +57,7 @@ defmodule CanneryWeb.AmmoGroupLive.Index do
socket
|> assign(
page_title: dgettext("actions", "Add Ammo"),
ammo_group: %{Ammo.get_ammo_group!(id, current_user) | id: nil}
pack: %{Ammo.get_pack!(id, current_user) | id: nil}
)
end
@ -60,7 +65,7 @@ defmodule CanneryWeb.AmmoGroupLive.Index do
socket
|> assign(
page_title: dgettext("actions", "Add Ammo"),
ammo_group: %AmmoGroup{}
pack: %Pack{}
)
end
@ -69,7 +74,7 @@ defmodule CanneryWeb.AmmoGroupLive.Index do
|> assign(
page_title: gettext("Ammo"),
search: nil,
ammo_group: nil
pack: nil
)
end
@ -78,86 +83,84 @@ defmodule CanneryWeb.AmmoGroupLive.Index do
|> assign(
page_title: gettext("Ammo"),
search: search,
ammo_group: nil
pack: nil
)
end
@impl true
def handle_event("delete", %{"id" => id}, %{assigns: %{current_user: current_user}} = socket) do
Ammo.get_ammo_group!(id, current_user) |> Ammo.delete_ammo_group!(current_user)
Ammo.get_pack!(id, current_user) |> Ammo.delete_pack!(current_user)
prompt = dgettext("prompts", "Ammo deleted succesfully")
{:noreply, socket |> put_flash(:info, prompt) |> display_ammo_groups()}
{:noreply, socket |> put_flash(:info, prompt) |> display_packs()}
end
def handle_event(
"toggle_staged",
%{"ammo_group_id" => id},
%{"pack_id" => id},
%{assigns: %{current_user: current_user}} = socket
) do
ammo_group = Ammo.get_ammo_group!(id, current_user)
pack = Ammo.get_pack!(id, current_user)
{:ok, _ammo_group} =
ammo_group |> Ammo.update_ammo_group(%{"staged" => !ammo_group.staged}, current_user)
{:ok, _pack} = pack |> Ammo.update_pack(%{"staged" => !pack.staged}, current_user)
{:noreply, socket |> display_ammo_groups()}
{:noreply, socket |> display_packs()}
end
def handle_event("toggle_show_used", _params, %{assigns: %{show_used: show_used}} = socket) do
{:noreply, socket |> assign(:show_used, !show_used) |> display_ammo_groups()}
{:noreply, socket |> assign(:show_used, !show_used) |> display_packs()}
end
def handle_event("search", %{"search" => %{"search_term" => ""}}, socket) do
{:noreply, socket |> push_patch(to: Routes.ammo_group_index_path(Endpoint, :index))}
{:noreply, socket |> push_patch(to: Routes.pack_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))
socket = socket |> push_patch(to: Routes.pack_index_path(Endpoint, :search, search_term))
{:noreply, socket}
end
def handle_event("change_type", %{"ammo_type" => %{"type" => "rifle"}}, socket) do
{:noreply, socket |> assign(:type, :rifle) |> display_ammo_groups()}
def handle_event("change_class", %{"ammo_type" => %{"class" => "rifle"}}, socket) do
{:noreply, socket |> assign(:class, :rifle) |> display_packs()}
end
def handle_event("change_type", %{"ammo_type" => %{"type" => "shotgun"}}, socket) do
{:noreply, socket |> assign(:type, :shotgun) |> display_ammo_groups()}
def handle_event("change_class", %{"ammo_type" => %{"class" => "shotgun"}}, socket) do
{:noreply, socket |> assign(:class, :shotgun) |> display_packs()}
end
def handle_event("change_type", %{"ammo_type" => %{"type" => "pistol"}}, socket) do
{:noreply, socket |> assign(:type, :pistol) |> display_ammo_groups()}
def handle_event("change_class", %{"ammo_type" => %{"class" => "pistol"}}, socket) do
{:noreply, socket |> assign(:class, :pistol) |> display_packs()}
end
def handle_event("change_type", %{"ammo_type" => %{"type" => _all}}, socket) do
{:noreply, socket |> assign(:type, :all) |> display_ammo_groups()}
def handle_event("change_class", %{"ammo_type" => %{"class" => _all}}, socket) do
{:noreply, socket |> assign(:class, :all) |> display_packs()}
end
defp display_ammo_groups(
defp display_packs(
%{
assigns: %{
type: type,
class: class,
search: search,
current_user: current_user,
show_used: show_used
}
} = socket
) do
# get total number of ammo groups to determine whether to display onboarding
# get total number of packs to determine whether to display onboarding
# prompts
ammo_groups_count = Ammo.get_ammo_groups_count!(current_user, true)
ammo_groups = Ammo.list_ammo_groups(search, type, current_user, show_used)
packs_count = Ammo.get_packs_count!(current_user, true)
packs = Ammo.list_packs(search, class, current_user, show_used)
ammo_types_count = Ammo.get_ammo_types_count!(current_user)
containers_count = Containers.get_containers_count!(current_user)
socket
|> assign(
ammo_groups: ammo_groups,
packs: packs,
ammo_types_count: ammo_types_count,
containers_count: containers_count,
ammo_groups_count: ammo_groups_count
packs_count: packs_count
)
end
end

View File

@ -24,17 +24,17 @@
<%= dgettext("actions", "add an ammo type first") %>
</.link>
</div>
<% @ammo_groups_count == 0 -> %>
<% @packs_count == 0 -> %>
<h2 class="title text-xl text-primary-600">
<%= gettext("No ammo") %>
<%= display_emoji("😔") %>
</h2>
<.link patch={Routes.ammo_group_index_path(Endpoint, :new)} class="btn btn-primary">
<.link patch={Routes.pack_index_path(Endpoint, :new)} class="btn btn-primary">
<%= dgettext("actions", "Add your first box!") %>
</.link>
<% true -> %>
<.link patch={Routes.ammo_group_index_path(Endpoint, :new)} class="btn btn-primary">
<.link patch={Routes.pack_index_path(Endpoint, :new)} class="btn btn-primary">
<%= dgettext("actions", "Add Ammo") %>
</.link>
@ -43,15 +43,17 @@
:let={f}
for={%{}}
as={:ammo_type}
phx-change="change_type"
phx-submit="change_type"
phx-change="change_class"
phx-submit="change_class"
class="flex items-center"
>
<%= label(f, :type, gettext("Type"), class: "title text-primary-600 text-lg text-center") %>
<%= label(f, :class, gettext("Class"),
class: "title text-primary-600 text-lg text-center"
) %>
<%= select(
f,
:type,
:class,
[
{gettext("All"), :all},
{gettext("Rifle"), :rifle},
@ -59,7 +61,7 @@
{gettext("Pistol"), :pistol}
],
class: "mx-2 my-1 min-w-md input input-primary",
value: @type
value: @class
) %>
</.form>
@ -87,16 +89,16 @@
</.toggle_button>
</div>
<%= if @ammo_groups |> Enum.empty?() do %>
<%= if @packs |> Enum.empty?() do %>
<h2 class="title text-xl text-primary-600">
<%= gettext("No Ammo") %>
<%= display_emoji("😔") %>
</h2>
<% else %>
<.live_component
module={CanneryWeb.Components.AmmoGroupTableComponent}
module={CanneryWeb.Components.PackTableComponent}
id="ammo-group-index-table"
ammo_groups={@ammo_groups}
packs={@packs}
current_user={@current_user}
show_used={@show_used}
>
@ -105,28 +107,28 @@
<%= ammo_type_name %>
</.link>
</:ammo_type>
<:range :let={ammo_group}>
<:range :let={pack}>
<div class="min-w-20 py-2 px-4 h-full flex flew-wrap justify-center items-center">
<button
type="button"
class="mx-2 my-1 text-sm btn btn-primary"
phx-click="toggle_staged"
phx-value-ammo_group_id={ammo_group.id}
phx-value-pack_id={pack.id}
>
<%= if ammo_group.staged,
<%= if pack.staged,
do: dgettext("actions", "Unstage"),
else: dgettext("actions", "Stage") %>
</button>
<.link
patch={Routes.ammo_group_index_path(Endpoint, :add_shot_group, ammo_group)}
patch={Routes.pack_index_path(Endpoint, :add_shot_group, pack)}
class="mx-2 my-1 text-sm btn btn-primary"
>
<%= dgettext("actions", "Record shots") %>
</.link>
</div>
</:range>
<:container :let={{ammo_group, %{name: container_name} = container}}>
<:container :let={{pack, %{name: container_name} = container}}>
<div class="min-w-20 py-2 px-4 h-full flex flew-wrap justify-center items-center">
<.link
navigate={Routes.container_show_path(Endpoint, :show, container)}
@ -136,45 +138,41 @@
</.link>
<.link
patch={Routes.ammo_group_index_path(Endpoint, :move, ammo_group)}
patch={Routes.pack_index_path(Endpoint, :move, pack)}
class="mx-2 my-1 text-sm btn btn-primary"
>
<%= dgettext("actions", "Move ammo") %>
</.link>
</div>
</:container>
<:actions :let={%{count: ammo_group_count} = ammo_group}>
<:actions :let={%{count: pack_count} = pack}>
<div class="py-2 px-4 h-full space-x-4 flex justify-center items-center">
<.link
navigate={Routes.ammo_group_show_path(Endpoint, :show, ammo_group)}
navigate={Routes.pack_show_path(Endpoint, :show, pack)}
class="text-primary-600 link"
aria-label={
dgettext("actions", "View ammo group of %{ammo_group_count} bullets",
ammo_group_count: ammo_group_count
)
dgettext("actions", "View pack of %{pack_count} bullets", pack_count: pack_count)
}
>
<i class="fa-fw fa-lg fas fa-eye"></i>
</.link>
<.link
patch={Routes.ammo_group_index_path(Endpoint, :edit, ammo_group)}
patch={Routes.pack_index_path(Endpoint, :edit, pack)}
class="text-primary-600 link"
aria-label={
dgettext("actions", "Edit ammo group of %{ammo_group_count} bullets",
ammo_group_count: ammo_group_count
)
dgettext("actions", "Edit pack of %{pack_count} bullets", pack_count: pack_count)
}
>
<i class="fa-fw fa-lg fas fa-edit"></i>
</.link>
<.link
patch={Routes.ammo_group_index_path(Endpoint, :clone, ammo_group)}
patch={Routes.pack_index_path(Endpoint, :clone, pack)}
class="text-primary-600 link"
aria-label={
dgettext("actions", "Clone ammo group of %{ammo_group_count} bullets",
ammo_group_count: ammo_group_count
dgettext("actions", "Clone pack of %{pack_count} bullets",
pack_count: pack_count
)
}
>
@ -185,11 +183,11 @@
href="#"
class="text-primary-600 link"
phx-click="delete"
phx-value-id={ammo_group.id}
phx-value-id={pack.id}
data-confirm={dgettext("prompts", "Are you sure you want to delete this ammo?")}
aria-label={
dgettext("actions", "Delete ammo group of %{ammo_group_count} bullets",
ammo_group_count: ammo_group_count
dgettext("actions", "Delete pack of %{pack_count} bullets",
pack_count: pack_count
)
}
>
@ -204,38 +202,38 @@
<%= case @live_action do %>
<% create when create in [:new, :edit, :clone] -> %>
<.modal return_to={Routes.ammo_group_index_path(Endpoint, :index)}>
<.modal return_to={Routes.pack_index_path(Endpoint, :index)}>
<.live_component
module={CanneryWeb.AmmoGroupLive.FormComponent}
id={@ammo_group.id || :new}
module={CanneryWeb.PackLive.FormComponent}
id={@pack.id || :new}
title={@page_title}
action={@live_action}
ammo_group={@ammo_group}
return_to={Routes.ammo_group_index_path(Endpoint, :index)}
pack={@pack}
return_to={Routes.pack_index_path(Endpoint, :index)}
current_user={@current_user}
/>
</.modal>
<% :add_shot_group -> %>
<.modal return_to={Routes.ammo_group_index_path(Endpoint, :index)}>
<.modal return_to={Routes.pack_index_path(Endpoint, :index)}>
<.live_component
module={CanneryWeb.Components.AddShotGroupComponent}
id={:new}
title={@page_title}
action={@live_action}
ammo_group={@ammo_group}
return_to={Routes.ammo_group_index_path(Endpoint, :index)}
pack={@pack}
return_to={Routes.pack_index_path(Endpoint, :index)}
current_user={@current_user}
/>
</.modal>
<% :move -> %>
<.modal return_to={Routes.ammo_group_index_path(Endpoint, :index)}>
<.modal return_to={Routes.pack_index_path(Endpoint, :index)}>
<.live_component
module={CanneryWeb.Components.MoveAmmoGroupComponent}
id={@ammo_group.id}
module={CanneryWeb.Components.MovePackComponent}
id={@pack.id}
title={@page_title}
action={@live_action}
ammo_group={@ammo_group}
return_to={Routes.ammo_group_index_path(Endpoint, :index)}
pack={@pack}
return_to={Routes.pack_index_path(Endpoint, :index)}
current_user={@current_user}
/>
</.modal>

View File

@ -1,11 +1,11 @@
defmodule CanneryWeb.AmmoGroupLive.Show do
defmodule CanneryWeb.PackLive.Show do
@moduledoc """
Liveview for showing and editing an Cannery.Ammo.AmmoGroup
Liveview for showing and editing an Cannery.Ammo.Pack
"""
use CanneryWeb, :live_view
alias Cannery.{ActivityLog, ActivityLog.ShotGroup}
alias Cannery.{Ammo, Ammo.AmmoGroup}
alias Cannery.{Ammo, Ammo.Pack}
alias Cannery.{ComparableDate, Containers}
alias CanneryWeb.Endpoint
alias Phoenix.LiveView.Socket
@ -24,7 +24,7 @@ defmodule CanneryWeb.AmmoGroupLive.Show do
socket =
socket
|> assign(page_title: page_title(live_action), shot_group: shot_group)
|> display_ammo_group(id)
|> display_pack(id)
{:noreply, socket}
end
@ -33,7 +33,7 @@ defmodule CanneryWeb.AmmoGroupLive.Show do
socket =
socket
|> assign(page_title: page_title(live_action))
|> display_ammo_group(id)
|> display_pack(id)
{:noreply, socket}
end
@ -48,12 +48,12 @@ defmodule CanneryWeb.AmmoGroupLive.Show do
def handle_event(
"delete",
_params,
%{assigns: %{ammo_group: ammo_group, current_user: current_user}} = socket
%{assigns: %{pack: pack, current_user: current_user}} = socket
) do
ammo_group |> Ammo.delete_ammo_group!(current_user)
pack |> Ammo.delete_pack!(current_user)
prompt = dgettext("prompts", "Ammo deleted succesfully")
redirect_to = Routes.ammo_group_index_path(socket, :index)
redirect_to = Routes.pack_index_path(socket, :index)
{:noreply, socket |> put_flash(:info, prompt) |> push_navigate(to: redirect_to)}
end
@ -61,31 +61,30 @@ defmodule CanneryWeb.AmmoGroupLive.Show do
def handle_event(
"toggle_staged",
_params,
%{assigns: %{ammo_group: ammo_group, current_user: current_user}} = socket
%{assigns: %{pack: pack, current_user: current_user}} = socket
) do
{:ok, ammo_group} =
ammo_group |> Ammo.update_ammo_group(%{"staged" => !ammo_group.staged}, current_user)
{:ok, pack} = pack |> Ammo.update_pack(%{"staged" => !pack.staged}, current_user)
{:noreply, socket |> display_ammo_group(ammo_group)}
{:noreply, socket |> display_pack(pack)}
end
def handle_event(
"delete_shot_group",
%{"id" => id},
%{assigns: %{ammo_group: %{id: ammo_group_id}, current_user: current_user}} = socket
%{assigns: %{pack: %{id: pack_id}, current_user: current_user}} = socket
) do
{:ok, _} =
ActivityLog.get_shot_group!(id, current_user)
|> ActivityLog.delete_shot_group(current_user)
prompt = dgettext("prompts", "Shot records deleted succesfully")
{:noreply, socket |> put_flash(:info, prompt) |> display_ammo_group(ammo_group_id)}
{:noreply, socket |> put_flash(:info, prompt) |> display_pack(pack_id)}
end
@spec display_ammo_group(Socket.t(), AmmoGroup.t() | AmmoGroup.id()) :: Socket.t()
defp display_ammo_group(
@spec display_pack(Socket.t(), Pack.t() | Pack.id()) :: Socket.t()
defp display_pack(
%{assigns: %{current_user: current_user}} = socket,
%AmmoGroup{container_id: container_id} = ammo_group
%Pack{container_id: container_id} = pack
) do
columns = [
%{label: gettext("Rounds shot"), key: :count},
@ -94,19 +93,19 @@ defmodule CanneryWeb.AmmoGroupLive.Show do
%{label: gettext("Actions"), key: :actions, sortable: false}
]
shot_groups = ActivityLog.list_shot_groups_for_ammo_group(ammo_group, current_user)
shot_groups = ActivityLog.list_shot_groups_for_pack(pack, current_user)
rows =
shot_groups
|> Enum.map(fn shot_group ->
ammo_group |> get_table_row_for_shot_group(shot_group, columns)
pack |> get_table_row_for_shot_group(shot_group, columns)
end)
socket
|> assign(
ammo_group: ammo_group,
original_count: Ammo.get_original_count(ammo_group, current_user),
percentage_remaining: Ammo.get_percentage_remaining(ammo_group, current_user),
pack: pack,
original_count: Ammo.get_original_count(pack, current_user),
percentage_remaining: Ammo.get_percentage_remaining(pack, current_user),
container: container_id && Containers.get_container!(container_id, current_user),
shot_groups: shot_groups,
columns: columns,
@ -114,15 +113,15 @@ defmodule CanneryWeb.AmmoGroupLive.Show do
)
end
defp display_ammo_group(%{assigns: %{current_user: current_user}} = socket, id),
do: display_ammo_group(socket, Ammo.get_ammo_group!(id, current_user))
defp display_pack(%{assigns: %{current_user: current_user}} = socket, id),
do: display_pack(socket, Ammo.get_pack!(id, current_user))
@spec display_currency(float()) :: String.t()
defp display_currency(float), do: :erlang.float_to_binary(float, decimals: 2)
@spec get_table_row_for_shot_group(AmmoGroup.t(), ShotGroup.t(), [map()]) :: map()
defp get_table_row_for_shot_group(ammo_group, %{id: id, date: date} = shot_group, columns) do
assigns = %{ammo_group: ammo_group, shot_group: shot_group}
@spec get_table_row_for_shot_group(Pack.t(), ShotGroup.t(), [map()]) :: map()
defp get_table_row_for_shot_group(pack, %{id: id, date: date} = shot_group, columns) do
assigns = %{pack: pack, shot_group: shot_group}
columns
|> Map.new(fn %{key: key} ->
@ -140,7 +139,7 @@ defmodule CanneryWeb.AmmoGroupLive.Show do
~H"""
<div class="px-4 py-2 space-x-4 flex justify-center items-center">
<.link
patch={Routes.ammo_group_show_path(Endpoint, :edit_shot_group, @ammo_group, @shot_group)}
patch={Routes.pack_show_path(Endpoint, :edit_shot_group, @pack, @shot_group)}
class="text-primary-600 link"
aria-label={
dgettext("actions", "Edit shot group of %{shot_group_count} shots",

View File

@ -1,12 +1,12 @@
<div class="mx-auto space-y-4 max-w-3xl flex flex-col justify-center items-center">
<h1 class="title text-2xl title-primary-500">
<%= @ammo_group.ammo_type.name %>
<%= @pack.ammo_type.name %>
</h1>
<div class="space-y-2 flex flex-col justify-center items-center">
<span class="rounded-lg title text-lg">
<%= gettext("Count:") %>
<%= @ammo_group.count %>
<%= @pack.count %>
</span>
<span class="rounded-lg title text-lg">
@ -19,28 +19,28 @@
<%= gettext("%{percentage}%", percentage: @percentage_remaining) %>
</span>
<%= if @ammo_group.notes do %>
<%= if @pack.notes do %>
<span class="rounded-lg title text-lg">
<%= gettext("Notes:") %>
<%= @ammo_group.notes %>
<%= @pack.notes %>
</span>
<% end %>
<span class="rounded-lg title text-lg">
<%= gettext("Purchased on:") %>
<.date id={"#{@ammo_group.id}-purchased-on"} date={@ammo_group.purchased_on} />
<.date id={"#{@pack.id}-purchased-on"} date={@pack.purchased_on} />
</span>
<%= if @ammo_group.price_paid do %>
<%= if @pack.price_paid do %>
<span class="rounded-lg title text-lg">
<%= gettext("Original cost:") %>
<%= gettext("$%{amount}", amount: display_currency(@ammo_group.price_paid)) %>
<%= gettext("$%{amount}", amount: display_currency(@pack.price_paid)) %>
</span>
<span class="rounded-lg title text-lg">
<%= gettext("Current value:") %>
<%= gettext("$%{amount}",
amount: display_currency(@ammo_group.price_paid * @percentage_remaining / 100)
amount: display_currency(@pack.price_paid * @percentage_remaining / 100)
) %>
</span>
<% end %>
@ -49,19 +49,17 @@
<div class="flex flex-col justify-center items-center">
<div class="flex flex-wrap justify-center items-center text-primary-600">
<.link
navigate={Routes.ammo_type_show_path(Endpoint, :show, @ammo_group.ammo_type)}
navigate={Routes.ammo_type_show_path(Endpoint, :show, @pack.ammo_type)}
class="mx-4 my-2 btn btn-primary"
>
<%= dgettext("actions", "View in Catalog") %>
</.link>
<.link
patch={Routes.ammo_group_show_path(Endpoint, :edit, @ammo_group)}
patch={Routes.pack_show_path(Endpoint, :edit, @pack)}
class="mx-4 my-2 text-primary-600 link"
aria-label={
dgettext("actions", "Edit ammo group of %{ammo_group_count} bullets",
ammo_group_count: @ammo_group.count
)
dgettext("actions", "Edit pack of %{pack_count} bullets", pack_count: @pack.count)
}
>
<i class="fa-fw fa-lg fas fa-edit"></i>
@ -73,9 +71,7 @@
phx-click="delete"
data-confirm={dgettext("prompts", "Are you sure you want to delete this ammo?")}
aria-label={
dgettext("actions", "Delete ammo group of %{ammo_group_count} bullets",
ammo_group_count: @ammo_group.count
)
dgettext("actions", "Delete pack of %{pack_count} bullets", pack_count: @pack.count)
}
>
<i class="fa-fw fa-lg fas fa-trash"></i>
@ -84,20 +80,17 @@
<div class="flex flex-wrap justify-center items-center text-primary-600">
<button type="button" class="mx-4 my-2 btn btn-primary" phx-click="toggle_staged">
<%= if @ammo_group.staged,
<%= if @pack.staged,
do: dgettext("actions", "Unstage from range"),
else: dgettext("actions", "Stage for range") %>
</button>
<.link
patch={Routes.ammo_group_show_path(Endpoint, :move, @ammo_group)}
class="btn btn-primary"
>
<.link patch={Routes.pack_show_path(Endpoint, :move, @pack)} class="btn btn-primary">
<%= dgettext("actions", "Move ammo") %>
</.link>
<.link
patch={Routes.ammo_group_show_path(Endpoint, :add_shot_group, @ammo_group)}
patch={Routes.pack_show_path(Endpoint, :add_shot_group, @pack)}
class="mx-4 my-2 btn btn-primary"
>
<%= dgettext("actions", "Record shots") %>
@ -128,7 +121,7 @@
<.live_component
module={CanneryWeb.Components.TableComponent}
id="ammo_group_shot_groups_table"
id="pack_shot_groups_table"
columns={@columns}
rows={@rows}
/>
@ -137,50 +130,50 @@
<%= case @live_action do %>
<% :edit -> %>
<.modal return_to={Routes.ammo_group_show_path(Endpoint, :show, @ammo_group)}>
<.modal return_to={Routes.pack_show_path(Endpoint, :show, @pack)}>
<.live_component
module={CanneryWeb.AmmoGroupLive.FormComponent}
id={@ammo_group.id}
module={CanneryWeb.PackLive.FormComponent}
id={@pack.id}
title={@page_title}
action={@live_action}
ammo_group={@ammo_group}
return_to={Routes.ammo_group_show_path(Endpoint, :show, @ammo_group)}
pack={@pack}
return_to={Routes.pack_show_path(Endpoint, :show, @pack)}
current_user={@current_user}
/>
</.modal>
<% :edit_shot_group -> %>
<.modal return_to={Routes.ammo_group_show_path(Endpoint, :show, @ammo_group)}>
<.modal return_to={Routes.pack_show_path(Endpoint, :show, @pack)}>
<.live_component
module={CanneryWeb.RangeLive.FormComponent}
id={@shot_group.id}
title={@page_title}
action={@live_action}
shot_group={@shot_group}
return_to={Routes.ammo_group_show_path(Endpoint, :show, @ammo_group)}
return_to={Routes.pack_show_path(Endpoint, :show, @pack)}
current_user={@current_user}
/>
</.modal>
<% :add_shot_group -> %>
<.modal return_to={Routes.ammo_group_show_path(Endpoint, :show, @ammo_group)}>
<.modal return_to={Routes.pack_show_path(Endpoint, :show, @pack)}>
<.live_component
module={CanneryWeb.Components.AddShotGroupComponent}
id={:new}
title={@page_title}
action={@live_action}
ammo_group={@ammo_group}
return_to={Routes.ammo_group_show_path(Endpoint, :show, @ammo_group)}
pack={@pack}
return_to={Routes.pack_show_path(Endpoint, :show, @pack)}
current_user={@current_user}
/>
</.modal>
<% :move -> %>
<.modal return_to={Routes.ammo_group_show_path(Endpoint, :show, @ammo_group)}>
<.modal return_to={Routes.pack_show_path(Endpoint, :show, @pack)}>
<.live_component
module={CanneryWeb.Components.MoveAmmoGroupComponent}
id={@ammo_group.id}
module={CanneryWeb.Components.MovePackComponent}
id={@pack.id}
title={@page_title}
action={@live_action}
ammo_group={@ammo_group}
return_to={Routes.ammo_group_show_path(Endpoint, :show, @ammo_group)}
pack={@pack}
return_to={Routes.pack_show_path(Endpoint, :show, @pack)}
current_user={@current_user}
/>
</.modal>

View File

@ -4,33 +4,33 @@ defmodule CanneryWeb.RangeLive.FormComponent do
"""
use CanneryWeb, :live_component
alias Cannery.{Accounts.User, ActivityLog, ActivityLog.ShotGroup, Ammo, Ammo.AmmoGroup}
alias Cannery.{Accounts.User, ActivityLog, ActivityLog.ShotGroup, Ammo, Ammo.Pack}
alias Ecto.Changeset
alias Phoenix.LiveView.Socket
@impl true
def mount(socket), do: {:ok, socket |> assign(:ammo_group, nil)}
def mount(socket), do: {:ok, socket |> assign(:pack, nil)}
@impl true
@spec update(
%{
required(:shot_group) => ShotGroup.t(),
required(:current_user) => User.t(),
optional(:ammo_group) => AmmoGroup.t(),
optional(:pack) => Pack.t(),
optional(any()) => any()
},
Socket.t()
) :: {:ok, Socket.t()}
def update(
%{
shot_group: %ShotGroup{ammo_group_id: ammo_group_id},
shot_group: %ShotGroup{pack_id: pack_id},
current_user: current_user
} = assigns,
socket
)
when is_binary(ammo_group_id) do
ammo_group = Ammo.get_ammo_group!(ammo_group_id, current_user)
{:ok, socket |> assign(assigns) |> assign(:ammo_group, ammo_group) |> assign_changeset(%{})}
when is_binary(pack_id) do
pack = Ammo.get_pack!(pack_id, current_user)
{:ok, socket |> assign(assigns) |> assign(:pack, pack) |> assign_changeset(%{})}
end
def update(%{shot_group: %ShotGroup{}} = assigns, socket) do
@ -66,7 +66,7 @@ defmodule CanneryWeb.RangeLive.FormComponent do
assigns: %{
action: live_action,
current_user: user,
ammo_group: ammo_group,
pack: pack,
shot_group: shot_group
}
} = socket,
@ -81,7 +81,7 @@ defmodule CanneryWeb.RangeLive.FormComponent do
changeset =
case default_action do
:insert -> shot_group |> ShotGroup.create_changeset(user, ammo_group, shot_group_params)
:insert -> shot_group |> ShotGroup.create_changeset(user, pack, shot_group_params)
:update -> shot_group |> ShotGroup.update_changeset(user, shot_group_params)
end

View File

@ -22,7 +22,7 @@
<%= label(f, :count, gettext("Shots fired"), class: "title text-lg text-primary-600") %>
<%= number_input(f, :count,
min: 1,
max: @shot_group.count + @ammo_group.count,
max: @shot_group.count + @pack.count,
class: "input input-primary col-span-2"
) %>
<%= error_tag(f, :count, "col-span-3") %>

View File

@ -1,6 +1,6 @@
defmodule CanneryWeb.RangeLive.Index do
@moduledoc """
Main page for range day mode, where `AmmoGroup`s can be used up.
Main page for range day mode, where `Pack`s can be used up.
"""
use CanneryWeb, :live_view
@ -10,11 +10,11 @@ defmodule CanneryWeb.RangeLive.Index do
@impl true
def mount(%{"search" => search}, _session, socket) do
{:ok, socket |> assign(type: :all, search: search) |> display_shot_groups()}
{:ok, socket |> assign(class: :all, search: search) |> display_shot_groups()}
end
def mount(_params, _session, socket) do
{:ok, socket |> assign(type: :all, search: nil) |> display_shot_groups()}
{:ok, socket |> assign(class: :all, search: nil) |> display_shot_groups()}
end
@impl true
@ -30,7 +30,7 @@ defmodule CanneryWeb.RangeLive.Index do
socket
|> assign(
page_title: gettext("Record Shots"),
ammo_group: Ammo.get_ammo_group!(id, current_user)
pack: Ammo.get_pack!(id, current_user)
)
end
@ -82,13 +82,12 @@ defmodule CanneryWeb.RangeLive.Index do
def handle_event(
"toggle_staged",
%{"ammo_group_id" => ammo_group_id},
%{"pack_id" => pack_id},
%{assigns: %{current_user: current_user}} = socket
) do
ammo_group = Ammo.get_ammo_group!(ammo_group_id, current_user)
pack = Ammo.get_pack!(pack_id, current_user)
{:ok, _ammo_group} =
ammo_group |> Ammo.update_ammo_group(%{"staged" => !ammo_group.staged}, current_user)
{:ok, _pack} = pack |> Ammo.update_pack(%{"staged" => !pack.staged}, current_user)
prompt = dgettext("prompts", "Ammo unstaged succesfully")
{:noreply, socket |> put_flash(:info, prompt) |> display_shot_groups()}
@ -102,41 +101,43 @@ defmodule CanneryWeb.RangeLive.Index do
{:noreply, socket |> push_patch(to: Routes.range_index_path(Endpoint, :search, search_term))}
end
def handle_event("change_type", %{"ammo_type" => %{"type" => "rifle"}}, socket) do
{:noreply, socket |> assign(:type, :rifle) |> display_shot_groups()}
def handle_event("change_class", %{"ammo_type" => %{"class" => "rifle"}}, socket) do
{:noreply, socket |> assign(:class, :rifle) |> display_shot_groups()}
end
def handle_event("change_type", %{"ammo_type" => %{"type" => "shotgun"}}, socket) do
{:noreply, socket |> assign(:type, :shotgun) |> display_shot_groups()}
def handle_event("change_class", %{"ammo_type" => %{"class" => "shotgun"}}, socket) do
{:noreply, socket |> assign(:class, :shotgun) |> display_shot_groups()}
end
def handle_event("change_type", %{"ammo_type" => %{"type" => "pistol"}}, socket) do
{:noreply, socket |> assign(:type, :pistol) |> display_shot_groups()}
def handle_event("change_class", %{"ammo_type" => %{"class" => "pistol"}}, socket) do
{:noreply, socket |> assign(:class, :pistol) |> display_shot_groups()}
end
def handle_event("change_type", %{"ammo_type" => %{"type" => _all}}, socket) do
{:noreply, socket |> assign(:type, :all) |> display_shot_groups()}
def handle_event("change_class", %{"ammo_type" => %{"class" => _all}}, socket) do
{:noreply, socket |> assign(:class, :all) |> display_shot_groups()}
end
@spec display_shot_groups(Socket.t()) :: Socket.t()
defp display_shot_groups(
%{assigns: %{type: type, search: search, current_user: current_user}} = socket
%{assigns: %{class: class, search: search, current_user: current_user}} = socket
) do
shot_groups = ActivityLog.list_shot_groups(search, type, current_user)
ammo_groups = Ammo.list_staged_ammo_groups(current_user)
shot_groups = ActivityLog.list_shot_groups(search, class, current_user)
packs = Ammo.list_staged_packs(current_user)
chart_data = shot_groups |> get_chart_data_for_shot_group()
original_counts = ammo_groups |> Ammo.get_original_counts(current_user)
cprs = ammo_groups |> Ammo.get_cprs(current_user)
last_used_dates = ammo_groups |> ActivityLog.get_last_used_dates(current_user)
original_counts = packs |> Ammo.get_original_counts(current_user)
cprs = packs |> Ammo.get_cprs(current_user)
last_used_dates = packs |> ActivityLog.get_last_used_dates(current_user)
shot_record_count = ActivityLog.get_shot_record_count!(current_user)
socket
|> assign(
ammo_groups: ammo_groups,
packs: packs,
original_counts: original_counts,
cprs: cprs,
last_used_dates: last_used_dates,
chart_data: chart_data,
shot_groups: shot_groups
shot_groups: shot_groups,
shot_record_count: shot_record_count
)
end

View File

@ -3,54 +3,54 @@
<%= gettext("Range day") %>
</h1>
<%= if @ammo_groups |> Enum.empty?() do %>
<%= if @packs |> Enum.empty?() do %>
<h1 class="title text-xl text-primary-600">
<%= gettext("No ammo staged") %>
<%= display_emoji("😔") %>
</h1>
<.link navigate={Routes.ammo_group_index_path(Endpoint, :index)} class="btn btn-primary">
<.link navigate={Routes.pack_index_path(Endpoint, :index)} class="btn btn-primary">
<%= dgettext("actions", "Why not get some ready to shoot?") %>
</.link>
<% else %>
<.link navigate={Routes.ammo_group_index_path(Endpoint, :index)} class="btn btn-primary">
<.link navigate={Routes.pack_index_path(Endpoint, :index)} class="btn btn-primary">
<%= dgettext("actions", "Stage ammo") %>
</.link>
<div class="w-full flex flex-row flex-wrap justify-center items-stretch">
<.ammo_group_card
:for={%{id: ammo_group_id} = ammo_group <- @ammo_groups}
ammo_group={ammo_group}
original_count={Map.fetch!(@original_counts, ammo_group_id)}
cpr={Map.get(@cprs, ammo_group_id)}
last_used_date={Map.get(@last_used_dates, ammo_group_id)}
<.pack_card
:for={%{id: pack_id} = pack <- @packs}
pack={pack}
original_count={Map.fetch!(@original_counts, pack_id)}
cpr={Map.get(@cprs, pack_id)}
last_used_date={Map.get(@last_used_dates, pack_id)}
current_user={@current_user}
>
<button
type="button"
class="btn btn-primary"
phx-click="toggle_staged"
phx-value-ammo_group_id={ammo_group.id}
phx-value-pack_id={pack.id}
data-confirm={"#{dgettext("prompts", "Are you sure you want to unstage this ammo?")}"}
>
<%= if ammo_group.staged,
<%= if pack.staged,
do: dgettext("actions", "Unstage from range"),
else: dgettext("actions", "Stage for range") %>
</button>
<.link
patch={Routes.range_index_path(Endpoint, :add_shot_group, ammo_group)}
patch={Routes.range_index_path(Endpoint, :add_shot_group, pack)}
class="btn btn-primary"
>
<%= dgettext("actions", "Record shots") %>
</.link>
</.ammo_group_card>
</.pack_card>
</div>
<% end %>
<hr class="hr" />
<%= if @shot_groups |> Enum.empty?() and @search |> is_nil() do %>
<%= if @shot_record_count == 0 do %>
<h1 class="title text-xl text-primary-600">
<%= gettext("No shots recorded") %>
<%= display_emoji("😔") %>
@ -79,15 +79,15 @@
:let={f}
for={%{}}
as={:ammo_type}
phx-change="change_type"
phx-submit="change_type"
phx-change="change_class"
phx-submit="change_class"
class="flex items-center"
>
<%= label(f, :type, gettext("Type"), class: "title text-primary-600 text-lg text-center") %>
<%= label(f, :class, gettext("Class"), class: "title text-primary-600 text-lg text-center") %>
<%= select(
f,
:type,
:class,
[
{gettext("All"), :all},
{gettext("Rifle"), :rifle},
@ -95,7 +95,7 @@
{gettext("Pistol"), :pistol}
],
class: "mx-2 my-1 min-w-md input input-primary",
value: @type
value: @class
) %>
</.form>
@ -186,7 +186,7 @@
id={:new}
title={@page_title}
action={@live_action}
ammo_group={@ammo_group}
pack={@pack}
return_to={Routes.range_index_path(Endpoint, :index)}
current_user={@current_user}
/>

View File

@ -89,19 +89,19 @@ defmodule CanneryWeb.Router do
live "/container/edit/:id", ContainerLive.Show, :edit
live "/container/edit_tags/:id", ContainerLive.Show, :edit_tags
live "/ammo", AmmoGroupLive.Index, :index
live "/ammo/new", AmmoGroupLive.Index, :new
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", PackLive.Index, :index
live "/ammo/new", PackLive.Index, :new
live "/ammo/edit/:id", PackLive.Index, :edit
live "/ammo/clone/:id", PackLive.Index, :clone
live "/ammo/add_shot_group/:id", PackLive.Index, :add_shot_group
live "/ammo/move/:id", PackLive.Index, :move
live "/ammo/search/:search", PackLive.Index, :search
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 "/ammo/show/:id", PackLive.Show, :show
live "/ammo/show/edit/:id", PackLive.Show, :edit
live "/ammo/show/add_shot_group/:id", PackLive.Show, :add_shot_group
live "/ammo/show/move/:id", PackLive.Show, :move
live "/ammo/show/:id/edit/:shot_group_id", PackLive.Show, :edit_shot_group
live "/range", RangeLive.Index, :index
live "/range/edit/:id", RangeLive.Index, :edit

View File

@ -10,14 +10,14 @@
msgid ""
msgstr ""
#: 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:38
#: lib/cannery_web/live/pack_live/index.ex:59
#: lib/cannery_web/live/pack_live/index.ex:67
#: lib/cannery_web/live/pack_live/index.html.heex:38
#, elixir-autogen, elixir-format
msgid "Add Ammo"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:34
#: lib/cannery_web/live/pack_live/index.html.heex:34
#, elixir-autogen, elixir-format
msgid "Add your first box!"
msgstr ""
@ -121,10 +121,10 @@ msgid "Reset password"
msgstr ""
#: lib/cannery_web/components/add_shot_group_component.html.heex:57
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:84
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:350
#: lib/cannery_web/live/container_live/form_component.html.heex:57
#: lib/cannery_web/live/invite_live/form_component.html.heex:35
#: lib/cannery_web/live/pack_live/form_component.html.heex:84
#: lib/cannery_web/live/range_live/form_component.html.heex:45
#: lib/cannery_web/live/tag_live/form_component.html.heex:37
#, elixir-autogen, elixir-format
@ -156,19 +156,19 @@ msgstr ""
msgid "Why not get some ready to shoot?"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:125
#: lib/cannery_web/live/ammo_group_live/show.html.heex:103
#: lib/cannery_web/live/pack_live/index.html.heex:127
#: lib/cannery_web/live/pack_live/show.html.heex:96
#: lib/cannery_web/live/range_live/index.html.heex:45
#, elixir-autogen, elixir-format
msgid "Record shots"
msgstr ""
#: lib/cannery_web/components/move_ammo_group_component.ex:90
#: lib/cannery_web/components/move_pack_component.ex:88
#, elixir-autogen, elixir-format
msgid "Add another container!"
msgstr ""
#: lib/cannery_web/components/move_ammo_group_component.ex:126
#: lib/cannery_web/components/move_pack_component.ex:124
#, elixir-autogen, elixir-format
msgid "Select"
msgstr ""
@ -178,12 +178,12 @@ msgstr ""
msgid "Copy to clipboard"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:14
#: lib/cannery_web/live/pack_live/index.html.heex:14
#, elixir-autogen, elixir-format
msgid "add a container first"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:77
#: lib/cannery_web/live/pack_live/form_component.html.heex:77
#, elixir-autogen, elixir-format
msgid "Create"
msgstr ""
@ -198,19 +198,19 @@ msgstr ""
msgid "Change language"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.html.heex:55
#: lib/cannery_web/live/pack_live/show.html.heex:55
#, elixir-autogen, elixir-format
msgid "View in Catalog"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:24
#: lib/cannery_web/live/pack_live/index.html.heex:24
#, elixir-autogen, elixir-format
msgid "add an ammo type first"
msgstr ""
#: lib/cannery_web/components/move_ammo_group_component.ex:80
#: lib/cannery_web/live/ammo_group_live/index.html.heex:142
#: lib/cannery_web/live/ammo_group_live/show.html.heex:96
#: lib/cannery_web/components/move_pack_component.ex:78
#: lib/cannery_web/live/pack_live/index.html.heex:144
#: lib/cannery_web/live/pack_live/show.html.heex:89
#, elixir-autogen, elixir-format
msgid "Move ammo"
msgstr ""
@ -220,13 +220,13 @@ msgstr ""
msgid "Set Unlimited"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.html.heex:89
#: lib/cannery_web/live/pack_live/show.html.heex:85
#: lib/cannery_web/live/range_live/index.html.heex:38
#, elixir-autogen, elixir-format
msgid "Stage for range"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.html.heex:88
#: lib/cannery_web/live/pack_live/show.html.heex:84
#: lib/cannery_web/live/range_live/index.html.heex:37
#, elixir-autogen, elixir-format
msgid "Unstage from range"
@ -276,7 +276,7 @@ msgstr ""
msgid "Delete invite for %{invite_name}"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.ex:161
#: lib/cannery_web/live/pack_live/show.ex:160
#: lib/cannery_web/live/range_live/index.html.heex:155
#, elixir-autogen, elixir-format
msgid "Delete shot record of %{shot_group_count} shots"
@ -300,18 +300,12 @@ msgstr ""
msgid "Edit %{tag_name}"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:164
#: lib/cannery_web/live/ammo_group_live/show.html.heex:62
#, elixir-autogen, elixir-format
msgid "Edit ammo group of %{ammo_group_count} bullets"
msgstr ""
#: lib/cannery_web/live/invite_live/index.html.heex:46
#, elixir-autogen, elixir-format
msgid "Edit invite for %{invite_name}"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.ex:146
#: lib/cannery_web/live/pack_live/show.ex:145
#, elixir-autogen, elixir-format
msgid "Edit shot group of %{shot_group_count} shots"
msgstr ""
@ -321,7 +315,7 @@ msgstr ""
msgid "Edit shot record of %{shot_group_count} shots"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:118
#: lib/cannery_web/live/pack_live/index.html.heex:120
#, elixir-autogen, elixir-format
msgid "Stage"
msgstr ""
@ -332,7 +326,7 @@ msgstr ""
msgid "Tag %{container_name}"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:117
#: lib/cannery_web/live/pack_live/index.html.heex:119
#, elixir-autogen, elixir-format
msgid "Unstage"
msgstr ""
@ -342,19 +336,25 @@ msgstr ""
msgid "View %{ammo_type_name}"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:176
#: lib/cannery_web/live/pack_live/index.html.heex:174
#, elixir-autogen, elixir-format
msgid "Clone ammo group of %{ammo_group_count} bullets"
msgid "Clone pack of %{pack_count} bullets"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:191
#: lib/cannery_web/live/ammo_group_live/show.html.heex:76
#: lib/cannery_web/live/pack_live/index.html.heex:189
#: lib/cannery_web/live/pack_live/show.html.heex:74
#, elixir-autogen, elixir-format
msgid "Delete ammo group of %{ammo_group_count} bullets"
msgid "Delete pack of %{pack_count} bullets"
msgstr ""
#: lib/cannery_web/live/pack_live/index.html.heex:164
#: lib/cannery_web/live/pack_live/show.html.heex:62
#, elixir-autogen, elixir-format
msgid "Edit pack of %{pack_count} bullets"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:152
#: lib/cannery_web/live/ammo_type_live/show.html.heex:206
#: lib/cannery_web/live/pack_live/index.html.heex:154
#, elixir-autogen, elixir-format
msgid "View ammo group of %{ammo_group_count} bullets"
msgid "View pack of %{pack_count} bullets"
msgstr ""

View File

@ -23,14 +23,14 @@ 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:54
#: lib/cannery_web/live/ammo_group_live/index.ex:62
#: lib/cannery_web/live/ammo_group_live/index.html.heex:38
#: lib/cannery_web/live/pack_live/index.ex:59
#: lib/cannery_web/live/pack_live/index.ex:67
#: lib/cannery_web/live/pack_live/index.html.heex:38
#, elixir-autogen, elixir-format
msgid "Add Ammo"
msgstr "Munition hinzufügen"
#: lib/cannery_web/live/ammo_group_live/index.html.heex:34
#: lib/cannery_web/live/pack_live/index.html.heex:34
#, elixir-autogen, elixir-format
msgid "Add your first box!"
msgstr "Fügen Sie ihre erste Box hinzu!"
@ -134,10 +134,10 @@ msgid "Reset password"
msgstr "Passwort zurücksetzen"
#: lib/cannery_web/components/add_shot_group_component.html.heex:57
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:84
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:350
#: lib/cannery_web/live/container_live/form_component.html.heex:57
#: lib/cannery_web/live/invite_live/form_component.html.heex:35
#: lib/cannery_web/live/pack_live/form_component.html.heex:84
#: lib/cannery_web/live/range_live/form_component.html.heex:45
#: lib/cannery_web/live/tag_live/form_component.html.heex:37
#, elixir-autogen, elixir-format
@ -169,19 +169,19 @@ 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:125
#: lib/cannery_web/live/ammo_group_live/show.html.heex:103
#: lib/cannery_web/live/pack_live/index.html.heex:127
#: lib/cannery_web/live/pack_live/show.html.heex:96
#: lib/cannery_web/live/range_live/index.html.heex:45
#, elixir-autogen, elixir-format
msgid "Record shots"
msgstr "Schüsse dokumentieren"
#: lib/cannery_web/components/move_ammo_group_component.ex:90
#: lib/cannery_web/components/move_pack_component.ex:88
#, elixir-autogen, elixir-format
msgid "Add another container!"
msgstr "Einen weiteren Behälter hinzufügen!"
#: lib/cannery_web/components/move_ammo_group_component.ex:126
#: lib/cannery_web/components/move_pack_component.ex:124
#, elixir-autogen, elixir-format
msgid "Select"
msgstr "Markieren"
@ -191,12 +191,12 @@ msgstr "Markieren"
msgid "Copy to clipboard"
msgstr "In die Zwischenablage kopieren"
#: lib/cannery_web/live/ammo_group_live/index.html.heex:14
#: lib/cannery_web/live/pack_live/index.html.heex:14
#, elixir-autogen, elixir-format
msgid "add a container first"
msgstr "Zuerst einen Behälter hinzufügen"
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:77
#: lib/cannery_web/live/pack_live/form_component.html.heex:77
#, elixir-autogen, elixir-format
msgid "Create"
msgstr "Erstellen"
@ -211,19 +211,19 @@ msgstr "Sprache wechseln"
msgid "Change language"
msgstr "Sprache wechseln"
#: lib/cannery_web/live/ammo_group_live/show.html.heex:55
#: lib/cannery_web/live/pack_live/show.html.heex:55
#, elixir-autogen, elixir-format
msgid "View in Catalog"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:24
#: lib/cannery_web/live/pack_live/index.html.heex:24
#, elixir-autogen, elixir-format
msgid "add an ammo type first"
msgstr ""
#: lib/cannery_web/components/move_ammo_group_component.ex:80
#: lib/cannery_web/live/ammo_group_live/index.html.heex:142
#: lib/cannery_web/live/ammo_group_live/show.html.heex:96
#: lib/cannery_web/components/move_pack_component.ex:78
#: lib/cannery_web/live/pack_live/index.html.heex:144
#: lib/cannery_web/live/pack_live/show.html.heex:89
#, elixir-autogen, elixir-format
msgid "Move ammo"
msgstr ""
@ -233,13 +233,13 @@ msgstr ""
msgid "Set Unlimited"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.html.heex:89
#: lib/cannery_web/live/pack_live/show.html.heex:85
#: lib/cannery_web/live/range_live/index.html.heex:38
#, elixir-autogen, elixir-format
msgid "Stage for range"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.html.heex:88
#: lib/cannery_web/live/pack_live/show.html.heex:84
#: lib/cannery_web/live/range_live/index.html.heex:37
#, elixir-autogen, elixir-format
msgid "Unstage from range"
@ -289,7 +289,7 @@ msgstr ""
msgid "Delete invite for %{invite_name}"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.ex:161
#: lib/cannery_web/live/pack_live/show.ex:160
#: lib/cannery_web/live/range_live/index.html.heex:155
#, elixir-autogen, elixir-format
msgid "Delete shot record of %{shot_group_count} shots"
@ -313,18 +313,12 @@ msgstr ""
msgid "Edit %{tag_name}"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:164
#: lib/cannery_web/live/ammo_group_live/show.html.heex:62
#, elixir-autogen, elixir-format
msgid "Edit ammo group of %{ammo_group_count} bullets"
msgstr ""
#: lib/cannery_web/live/invite_live/index.html.heex:46
#, elixir-autogen, elixir-format
msgid "Edit invite for %{invite_name}"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.ex:146
#: lib/cannery_web/live/pack_live/show.ex:145
#, elixir-autogen, elixir-format
msgid "Edit shot group of %{shot_group_count} shots"
msgstr ""
@ -334,7 +328,7 @@ msgstr ""
msgid "Edit shot record of %{shot_group_count} shots"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:118
#: lib/cannery_web/live/pack_live/index.html.heex:120
#, elixir-autogen, elixir-format, fuzzy
msgid "Stage"
msgstr "Munition markieren"
@ -345,7 +339,7 @@ msgstr "Munition markieren"
msgid "Tag %{container_name}"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:117
#: lib/cannery_web/live/pack_live/index.html.heex:119
#, elixir-autogen, elixir-format
msgid "Unstage"
msgstr ""
@ -355,19 +349,25 @@ msgstr ""
msgid "View %{ammo_type_name}"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:176
#: lib/cannery_web/live/pack_live/index.html.heex:174
#, elixir-autogen, elixir-format, fuzzy
msgid "Clone ammo group of %{ammo_group_count} bullets"
msgid "Clone pack of %{pack_count} bullets"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:191
#: lib/cannery_web/live/ammo_group_live/show.html.heex:76
#: lib/cannery_web/live/pack_live/index.html.heex:189
#: lib/cannery_web/live/pack_live/show.html.heex:74
#, elixir-autogen, elixir-format, fuzzy
msgid "Delete ammo group of %{ammo_group_count} bullets"
msgid "Delete pack of %{pack_count} bullets"
msgstr ""
#: lib/cannery_web/live/pack_live/index.html.heex:164
#: lib/cannery_web/live/pack_live/show.html.heex:62
#, elixir-autogen, elixir-format, fuzzy
msgid "Edit pack of %{pack_count} bullets"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:152
#: lib/cannery_web/live/ammo_type_live/show.html.heex:206
#: lib/cannery_web/live/pack_live/index.html.heex:154
#, elixir-autogen, elixir-format, fuzzy
msgid "View ammo group of %{ammo_group_count} bullets"
msgid "View pack of %{pack_count} bullets"
msgstr ""

View File

@ -31,15 +31,15 @@ msgstr "Admins:"
#: lib/cannery_web/components/core_components/topbar.html.heex:58
#: lib/cannery_web/components/shot_group_table_component.ex:41
#: 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/pack_live/index.ex:75
#: lib/cannery_web/live/pack_live/index.ex:84
#: lib/cannery_web/live/pack_live/index.html.heex:3
#, elixir-autogen, elixir-format
msgid "Ammo"
msgstr "Munition"
#: lib/cannery_web/components/ammo_group_table_component.ex:96
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:22
#: lib/cannery_web/components/pack_table_component.ex:95
#: lib/cannery_web/live/pack_live/form_component.html.heex:22
#, elixir-autogen, elixir-format
msgid "Ammo type"
msgstr "Munitionsarten"
@ -90,9 +90,9 @@ msgstr "Patrone"
msgid "Case material"
msgstr "Gehäusematerial"
#: lib/cannery_web/components/ammo_group_table_component.ex:74
#: lib/cannery_web/components/move_ammo_group_component.ex:67
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:59
#: lib/cannery_web/components/move_pack_component.ex:65
#: lib/cannery_web/components/pack_table_component.ex:73
#: lib/cannery_web/live/pack_live/form_component.html.heex:59
#, elixir-autogen, elixir-format
msgid "Container"
msgstr "Behälter"
@ -111,14 +111,14 @@ msgstr "Behälter"
msgid "Corrosive"
msgstr "Korrosiv"
#: lib/cannery_web/components/ammo_group_table_component.ex:92
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:28
#: lib/cannery_web/components/pack_table_component.ex:91
#: lib/cannery_web/live/pack_live/form_component.html.heex:28
#, elixir-autogen, elixir-format
msgid "Count"
msgstr "Anzahl"
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:16
#: lib/cannery_web/live/ammo_group_live/show.html.heex:8
#: lib/cannery_web/components/core_components/pack_card.html.heex:16
#: lib/cannery_web/live/pack_live/show.html.heex:8
#, elixir-autogen, elixir-format
msgid "Count:"
msgstr "Anzahl:"
@ -196,7 +196,7 @@ msgid "Keep me logged in for 60 days"
msgstr "Für 60 Tage eingeloggt bleiben"
#: lib/cannery_web/components/container_table_component.ex:47
#: lib/cannery_web/components/move_ammo_group_component.ex:69
#: lib/cannery_web/components/move_pack_component.ex:67
#: lib/cannery_web/live/container_live/form_component.html.heex:47
#, elixir-autogen, elixir-format
msgid "Location"
@ -262,7 +262,7 @@ msgstr "Neue Einladung"
msgid "New Tag"
msgstr "Neuer Tag"
#: lib/cannery_web/live/ammo_group_live/index.html.heex:92
#: lib/cannery_web/live/pack_live/index.html.heex:94
#, elixir-autogen, elixir-format
msgid "No Ammo"
msgstr "Keine Munition"
@ -292,15 +292,15 @@ msgstr "Keine Tags"
#: lib/cannery_web/components/add_shot_group_component.html.heex:38
#: lib/cannery_web/components/shot_group_table_component.ex:43
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:50
#: lib/cannery_web/live/ammo_group_live/show.ex:92
#: lib/cannery_web/live/pack_live/form_component.html.heex:50
#: lib/cannery_web/live/pack_live/show.ex:91
#: lib/cannery_web/live/range_live/form_component.html.heex:30
#, elixir-autogen, elixir-format
msgid "Notes"
msgstr "Bemerkungen"
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:29
#: lib/cannery_web/live/ammo_group_live/show.html.heex:24
#: lib/cannery_web/components/core_components/pack_card.html.heex:26
#: lib/cannery_web/live/pack_live/show.html.heex:24
#, elixir-autogen, elixir-format
msgid "Notes:"
msgstr "Bemerkungen:"
@ -316,13 +316,13 @@ msgstr "Auf dem Bücherregal"
msgid "Pressure"
msgstr "Druck"
#: lib/cannery_web/components/ammo_group_table_component.ex:82
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:35
#: lib/cannery_web/components/pack_table_component.ex:81
#: lib/cannery_web/live/pack_live/form_component.html.heex:35
#, elixir-autogen, elixir-format
msgid "Price paid"
msgstr "Kaufpreis"
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:44
#: lib/cannery_web/components/core_components/pack_card.html.heex:41
#, elixir-autogen, elixir-format
msgid "Price paid:"
msgstr "Kaufpreis:"
@ -366,7 +366,7 @@ msgstr "Einfach:"
msgid "Steel"
msgstr "Stahl"
#: lib/cannery_web/live/ammo_group_live/show.html.heex:113
#: lib/cannery_web/live/pack_live/show.html.heex:106
#, elixir-autogen, elixir-format
msgid "Stored in"
msgstr "Gelagert in"
@ -401,16 +401,9 @@ msgstr "Die selbst-gehostete Website zur Verwaltung von Schusswaffen"
msgid "Tracer"
msgstr "Leuchtspur"
#: lib/cannery_web/components/ammo_type_table_component.ex:150
#: lib/cannery_web/components/container_table_component.ex:48
#: lib/cannery_web/components/move_ammo_group_component.ex:68
#: lib/cannery_web/live/ammo_group_live/index.html.heex:50
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:21
#: lib/cannery_web/live/ammo_type_live/index.html.heex:29
#: lib/cannery_web/live/ammo_type_live/show.html.heex:48
#: lib/cannery_web/components/move_pack_component.ex:66
#: lib/cannery_web/live/container_live/form_component.html.heex:39
#: lib/cannery_web/live/container_live/show.html.heex:97
#: lib/cannery_web/live/range_live/index.html.heex:86
#, elixir-autogen, elixir-format
msgid "Type"
msgstr "Art"
@ -441,8 +434,8 @@ msgstr "Ihre Daten bleiben bei Ihnen, Punkt"
msgid "No tags for this container"
msgstr "Keine Tags für diesen Behälter"
#: lib/cannery_web/components/ammo_group_table_component.ex:78
#: lib/cannery_web/components/core_components/topbar.html.heex:66
#: lib/cannery_web/components/pack_table_component.ex:77
#, elixir-autogen, elixir-format
msgid "Range"
msgstr "Schießplatz"
@ -454,7 +447,7 @@ msgstr "Range Day"
#: lib/cannery_web/components/add_shot_group_component.html.heex:49
#: lib/cannery_web/components/shot_group_table_component.ex:44
#: lib/cannery_web/live/ammo_group_live/show.ex:93
#: lib/cannery_web/live/pack_live/show.ex:92
#: lib/cannery_web/live/range_live/form_component.html.heex:41
#, elixir-autogen, elixir-format
msgid "Date"
@ -471,12 +464,12 @@ 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:30
#: lib/cannery_web/live/pack_live/index.ex:35
#, elixir-autogen, elixir-format
msgid "Record shots"
msgstr "Schüsse dokumentieren"
#: lib/cannery_web/live/ammo_group_live/show.ex:42
#: lib/cannery_web/live/pack_live/show.ex:42
#: lib/cannery_web/live/range_live/index.ex:40
#, elixir-autogen, elixir-format
msgid "Edit Shot Records"
@ -500,7 +493,7 @@ msgid "Rounds left"
msgstr "Patronen verbleibend"
#: lib/cannery_web/components/shot_group_table_component.ex:42
#: lib/cannery_web/live/ammo_group_live/show.ex:91
#: lib/cannery_web/live/pack_live/show.ex:90
#: lib/cannery_web/live/range_live/index.html.heex:69
#, elixir-autogen, elixir-format
msgid "Rounds shot"
@ -512,12 +505,12 @@ msgstr "Patronen abgefeuert"
msgid "Shot Records"
msgstr "Schießkladde"
#: lib/cannery_web/live/ammo_group_live/index.ex:38
#: lib/cannery_web/live/pack_live/index.ex:43
#, elixir-autogen, elixir-format
msgid "Move ammo"
msgstr "Munition verschieben"
#: lib/cannery_web/components/move_ammo_group_component.ex:85
#: lib/cannery_web/components/move_pack_component.ex:83
#, elixir-autogen, elixir-format
msgid "No other containers"
msgstr "Kein weiterer Behälter"
@ -527,14 +520,14 @@ msgstr "Kein weiterer Behälter"
msgid "Shot log"
msgstr "Schießkladde"
#: lib/cannery_web/components/ammo_group_table_component.ex:164
#: lib/cannery_web/components/ammo_group_table_component.ex:247
#: lib/cannery_web/components/ammo_type_table_component.ex:261
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:45
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:50
#: lib/cannery_web/live/ammo_group_live/show.html.heex:37
#: lib/cannery_web/live/ammo_group_live/show.html.heex:42
#: lib/cannery_web/components/core_components/pack_card.html.heex:42
#: lib/cannery_web/components/core_components/pack_card.html.heex:47
#: lib/cannery_web/components/pack_table_component.ex:163
#: lib/cannery_web/components/pack_table_component.ex:246
#: lib/cannery_web/live/ammo_type_live/show.html.heex:152
#: lib/cannery_web/live/pack_live/show.html.heex:37
#: lib/cannery_web/live/pack_live/show.html.heex:42
#, elixir-autogen, elixir-format
msgid "$%{amount}"
msgstr "$%{amount}"
@ -621,40 +614,40 @@ msgstr "Editiere %{name} Tags"
msgid "Rounds:"
msgstr "Patronen:"
#: lib/cannery_web/components/ammo_group_table_component.ex:161
#: lib/cannery_web/components/ammo_group_table_component.ex:243
#: lib/cannery_web/components/ammo_type_table_component.ex:260
#: lib/cannery_web/components/pack_table_component.ex:160
#: lib/cannery_web/components/pack_table_component.ex:242
#: lib/cannery_web/live/ammo_type_live/show.html.heex:156
#, elixir-autogen, elixir-format
msgid "No cost information"
msgstr "Keine Preisinformationen"
#: lib/cannery_web/components/ammo_group_table_component.ex:84
#: lib/cannery_web/components/pack_table_component.ex:83
#, elixir-autogen, elixir-format
msgid "% left"
msgstr "% verbleibend"
#: lib/cannery_web/live/ammo_group_live/show.html.heex:41
#: lib/cannery_web/live/pack_live/show.html.heex:41
#, elixir-autogen, elixir-format
msgid "Current value:"
msgstr "Derzeitiger Wert:"
#: lib/cannery_web/live/ammo_group_live/show.html.heex:36
#: lib/cannery_web/live/pack_live/show.html.heex:36
#, elixir-autogen, elixir-format
msgid "Original cost:"
msgstr "Originalpreis:"
#: lib/cannery_web/live/ammo_group_live/show.html.heex:13
#: lib/cannery_web/live/pack_live/show.html.heex:13
#, elixir-autogen, elixir-format
msgid "Original count:"
msgstr "Ursprüngliche Anzahl:"
#: lib/cannery_web/live/ammo_group_live/show.html.heex:18
#: lib/cannery_web/live/pack_live/show.html.heex:18
#, elixir-autogen, elixir-format
msgid "Percentage left:"
msgstr "Prozent verbleibend:"
#: lib/cannery_web/live/ammo_group_live/show.html.heex:126
#: lib/cannery_web/live/pack_live/show.html.heex:119
#, elixir-autogen, elixir-format
msgid "Rounds used"
msgstr "Patronen verbraucht"
@ -684,13 +677,13 @@ msgstr "Registrieren"
msgid "Reset your password"
msgstr "Passwort zurücksetzen"
#: lib/cannery_web/live/ammo_group_live/show.ex:41
#: lib/cannery_web/live/pack_live/show.ex:41
#: lib/cannery_web/live/range_live/index.ex:32
#, elixir-autogen, elixir-format
msgid "Record Shots"
msgstr "Schüsse dokumentieren"
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:69
#: lib/cannery_web/live/pack_live/form_component.html.heex:69
#, elixir-autogen, elixir-format
msgid "Copies"
msgstr "Kopien"
@ -749,12 +742,12 @@ msgstr "Quellcode ansehen"
msgid "Catalog"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.ex:45
#: lib/cannery_web/live/pack_live/show.ex:45
#, elixir-autogen, elixir-format, fuzzy
msgid "Edit Ammo"
msgstr "Munitionstyp bearbeiten"
#: lib/cannery_web/live/ammo_group_live/show.ex:43
#: lib/cannery_web/live/pack_live/show.ex:43
#, elixir-autogen, elixir-format, fuzzy
msgid "Move Ammo"
msgstr "Munition verschieben"
@ -764,12 +757,12 @@ msgstr "Munition verschieben"
msgid "No ammo in this container"
msgstr "Keine Munitionsgruppe in diesem Behälter"
#: lib/cannery_web/live/ammo_group_live/show.ex:44
#: lib/cannery_web/live/pack_live/show.ex:44
#, elixir-autogen, elixir-format, fuzzy
msgid "Show Ammo"
msgstr "Zeige Munitionsarten"
#: lib/cannery_web/live/ammo_group_live/show.html.heex:118
#: lib/cannery_web/live/pack_live/show.html.heex:111
#, elixir-autogen, elixir-format, fuzzy
msgid "This ammo is not in a container"
msgstr "Diese Munitionsgruppe ist nicht in einem Behälter"
@ -797,25 +790,25 @@ msgstr ""
msgid "Leave \"Uses left\" blank to make invite unlimited"
msgstr ""
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:54
#: lib/cannery_web/components/core_components/pack_card.html.heex:51
#, elixir-autogen, elixir-format, fuzzy
msgid "Container:"
msgstr "Behälter"
#: lib/cannery_web/live/ammo_group_live/index.html.heex:85
#: lib/cannery_web/live/ammo_type_live/index.html.heex:64
#: lib/cannery_web/live/ammo_type_live/show.html.heex:166
#: lib/cannery_web/live/pack_live/index.html.heex:87
#, elixir-autogen, elixir-format
msgid "Show used"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:202
#: lib/cannery_web/live/ammo_group_live/show.html.heex:19
#: lib/cannery_web/components/pack_table_component.ex:201
#: lib/cannery_web/live/pack_live/show.html.heex:19
#, elixir-autogen, elixir-format
msgid "%{percentage}%"
msgstr ""
#: lib/cannery_web/live/range_live/index.ex:153
#: lib/cannery_web/live/range_live/index.ex:154
#, elixir-autogen, elixir-format, fuzzy
msgid "Rounds shot: %{count}"
msgstr "Patronen abgefeuert"
@ -996,28 +989,28 @@ msgstr ""
msgid "Edit %{ammo_type_name}"
msgstr "%{name} bearbeiten"
#: lib/cannery_web/components/ammo_group_table_component.ex:251
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:17
#: lib/cannery_web/components/core_components/pack_card.html.heex:17
#: lib/cannery_web/components/pack_table_component.ex:250
#, elixir-autogen, elixir-format
msgid "Empty"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:81
#: lib/cannery_web/components/pack_table_component.ex:80
#, elixir-autogen, elixir-format
msgid "CPR"
msgstr ""
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:49
#: lib/cannery_web/components/core_components/pack_card.html.heex:46
#, elixir-autogen, elixir-format
msgid "CPR:"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:88
#: lib/cannery_web/components/pack_table_component.ex:87
#, elixir-autogen, elixir-format, fuzzy
msgid "Original Count"
msgstr "Ursprüngliche Anzahl:"
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:24
#: lib/cannery_web/components/core_components/pack_card.html.heex:21
#, elixir-autogen, elixir-format, fuzzy
msgid "Original Count:"
msgstr "Ursprüngliche Anzahl:"
@ -1027,34 +1020,34 @@ msgstr "Ursprüngliche Anzahl:"
msgid "Home"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:64
#: lib/cannery_web/components/pack_table_component.ex:63
#, elixir-autogen, elixir-format
msgid "Last used on"
msgstr ""
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:39
#: lib/cannery_web/components/core_components/pack_card.html.heex:36
#, elixir-autogen, elixir-format
msgid "Last used on:"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:182
#: lib/cannery_web/components/pack_table_component.ex:181
#, elixir-autogen, elixir-format
msgid "Never used"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:69
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:42
#: lib/cannery_web/components/pack_table_component.ex:68
#: lib/cannery_web/live/pack_live/form_component.html.heex:42
#, elixir-autogen, elixir-format
msgid "Purchased on"
msgstr ""
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:34
#: lib/cannery_web/live/ammo_group_live/show.html.heex:30
#: lib/cannery_web/components/core_components/pack_card.html.heex:31
#: lib/cannery_web/live/pack_live/show.html.heex:30
#, elixir-autogen, elixir-format
msgid "Purchased on:"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.ex:46
#: lib/cannery_web/live/pack_live/index.ex:51
#, elixir-autogen, elixir-format, fuzzy
msgid "Edit ammo"
msgstr "Munitionstyp bearbeiten"
@ -1070,7 +1063,7 @@ msgstr "Keine Munitionsarten"
msgid "Search catalog"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:79
#: lib/cannery_web/live/pack_live/index.html.heex:81
#, elixir-autogen, elixir-format, fuzzy
msgid "Search ammo"
msgstr ""
@ -1225,12 +1218,12 @@ msgstr ""
msgid "Really great weather"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:60
#: lib/cannery_web/components/ammo_type_table_component.ex:100
#: lib/cannery_web/components/container_table_component.ex:67
#: lib/cannery_web/components/move_ammo_group_component.ex:70
#: lib/cannery_web/components/move_pack_component.ex:68
#: lib/cannery_web/components/pack_table_component.ex:59
#: lib/cannery_web/components/shot_group_table_component.ex:45
#: lib/cannery_web/live/ammo_group_live/show.ex:94
#: lib/cannery_web/live/pack_live/show.ex:93
#, elixir-autogen, elixir-format
msgid "Actions"
msgstr ""
@ -1245,7 +1238,7 @@ msgstr ""
msgid "Log out"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:92
#: lib/cannery_web/components/pack_table_component.ex:91
#, elixir-autogen, elixir-format
msgid "Current Count"
msgstr ""
@ -1256,9 +1249,9 @@ msgstr ""
msgid "Close modal"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:56
#: lib/cannery_web/live/ammo_type_live/index.html.heex:35
#: lib/cannery_web/live/container_live/show.html.heex:103
#: lib/cannery_web/live/pack_live/index.html.heex:58
#: lib/cannery_web/live/range_live/index.html.heex:92
#, elixir-autogen, elixir-format
msgid "All"
@ -1330,7 +1323,7 @@ msgstr ""
msgid "Load grains:"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:29
#: lib/cannery_web/live/pack_live/index.html.heex:29
#, elixir-autogen, elixir-format, fuzzy
msgid "No ammo"
msgstr "Keine Munition"
@ -1340,11 +1333,11 @@ msgstr "Keine Munition"
msgid "None specified"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:59
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:25
#: lib/cannery_web/live/ammo_type_live/index.html.heex:38
#: lib/cannery_web/live/ammo_type_live/show.html.heex:58
#: lib/cannery_web/live/container_live/show.html.heex:106
#: lib/cannery_web/live/pack_live/index.html.heex:61
#: lib/cannery_web/live/range_live/index.html.heex:95
#, elixir-autogen, elixir-format
msgid "Pistol"
@ -1365,11 +1358,11 @@ msgstr "Zündertyp"
msgid "Projectile"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:57
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:25
#: lib/cannery_web/live/ammo_type_live/index.html.heex:36
#: lib/cannery_web/live/ammo_type_live/show.html.heex:56
#: lib/cannery_web/live/container_live/show.html.heex:104
#: lib/cannery_web/live/pack_live/index.html.heex:59
#: lib/cannery_web/live/range_live/index.html.heex:93
#, elixir-autogen, elixir-format
msgid "Rifle"
@ -1419,11 +1412,11 @@ msgstr ""
msgid "Shot type:"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:58
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:25
#: lib/cannery_web/live/ammo_type_live/index.html.heex:37
#: lib/cannery_web/live/ammo_type_live/show.html.heex:54
#: lib/cannery_web/live/container_live/show.html.heex:105
#: lib/cannery_web/live/pack_live/index.html.heex:60
#: lib/cannery_web/live/range_live/index.html.heex:94
#, elixir-autogen, elixir-format
msgid "Shotgun"
@ -1461,3 +1454,14 @@ msgstr ""
#, elixir-autogen, elixir-format
msgid "Wadding:"
msgstr ""
#: lib/cannery_web/components/ammo_type_table_component.ex:150
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:21
#: lib/cannery_web/live/ammo_type_live/index.html.heex:29
#: lib/cannery_web/live/ammo_type_live/show.html.heex:48
#: lib/cannery_web/live/container_live/show.html.heex:97
#: lib/cannery_web/live/pack_live/index.html.heex:50
#: lib/cannery_web/live/range_live/index.html.heex:86
#, elixir-autogen, elixir-format
msgid "Class"
msgstr ""

View File

@ -161,24 +161,24 @@ msgstr ""
msgid "Tag could not be removed"
msgstr "Tag konnte nicht gelöscht werden"
#: lib/cannery_web/live/ammo_group_live/form_component.ex:160
#: lib/cannery_web/live/pack_live/form_component.ex:159
#, elixir-autogen, elixir-format
msgid "Could not parse number of copies"
msgstr "Konnte die Anzahl der Kopien nicht verstehen"
#: lib/cannery_web/live/ammo_group_live/form_component.ex:150
#: lib/cannery_web/live/pack_live/form_component.ex:149
#, elixir-autogen, elixir-format
msgid "Invalid number of copies, must be between 1 and %{max}. Was %{multiplier}"
msgstr ""
"Ungültige Nummer an Kopien. Muss zwischen 1 and %{max} liegen. War "
"%{multiplier}"
#: lib/cannery/ammo.ex:1114
#: lib/cannery/ammo.ex:1123
#, elixir-autogen, elixir-format
msgid "Invalid multiplier"
msgstr ""
#: lib/cannery/ammo/ammo_group.ex:92
#: lib/cannery/ammo/pack.ex:92
#, elixir-autogen, elixir-format
msgid "Please select an ammo type and container"
msgstr ""
@ -203,7 +203,7 @@ msgstr ""
msgid "Ammo left must be at least 0"
msgstr ""
#: lib/cannery/activity_log/shot_group.ex:122
#: lib/cannery/activity_log/shot_group.ex:119
#, elixir-autogen, elixir-format, fuzzy
msgid "Count can be at most %{count} shots"
msgstr "Anzahl muss weniger als %{count} betragen"

View File

@ -73,8 +73,8 @@ msgstr ""
msgid "Are you sure you want to delete %{name}?"
msgstr "Sind Sie sicher, dass sie %{name} löschen möchten?"
#: lib/cannery_web/live/ammo_group_live/index.html.heex:189
#: lib/cannery_web/live/ammo_group_live/show.html.heex:74
#: lib/cannery_web/live/pack_live/index.html.heex:187
#: lib/cannery_web/live/pack_live/show.html.heex:72
#, elixir-autogen, elixir-format
msgid "Are you sure you want to delete this ammo?"
msgstr "Sind Sie sicher, dass sie diese Munition löschen möchten?"
@ -129,10 +129,10 @@ msgid "Please check your email to verify your account"
msgstr "Bitte überprüfen Sie ihre Mailbox und bestätigen Sie das Nutzerkonto"
#: lib/cannery_web/components/add_shot_group_component.html.heex:59
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:85
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:351
#: lib/cannery_web/live/container_live/form_component.html.heex:59
#: lib/cannery_web/live/invite_live/form_component.html.heex:37
#: lib/cannery_web/live/pack_live/form_component.html.heex:85
#: lib/cannery_web/live/range_live/form_component.html.heex:47
#: lib/cannery_web/live/tag_live/form_component.html.heex:39
#, elixir-autogen, elixir-format
@ -176,13 +176,13 @@ msgstr "Schüsse erfolgreich dokumentiert"
msgid "Are you sure you want to unstage this ammo?"
msgstr "Sind sie sicher, dass Sie diese Munition demarkieren möchten?"
#: lib/cannery_web/live/ammo_group_live/show.ex:159
#: lib/cannery_web/live/pack_live/show.ex:158
#: lib/cannery_web/live/range_live/index.html.heex:152
#, elixir-autogen, elixir-format
msgid "Are you sure you want to delete this shot record?"
msgstr "Sind sie sicher, dass sie die Schießkladde löschen möchten?"
#: lib/cannery_web/live/ammo_group_live/show.ex:81
#: lib/cannery_web/live/pack_live/show.ex:80
#: lib/cannery_web/live/range_live/index.ex:79
#, elixir-autogen, elixir-format
msgid "Shot records deleted succesfully"
@ -198,7 +198,7 @@ msgstr "Schießkladde erfolgreich aktualisiert"
msgid "%{email} confirmed successfully."
msgstr "%{email} erfolgreich bestätigt."
#: lib/cannery_web/components/move_ammo_group_component.ex:54
#: lib/cannery_web/components/move_pack_component.ex:52
#, elixir-autogen, elixir-format
msgid "Ammo moved to %{name} successfully"
msgstr "Munition erfolgreich zu %{name} verschoben"
@ -213,13 +213,13 @@ msgstr "Der Zwischenablage hinzugefügt"
msgid "%{name} removed successfully"
msgstr "%{name} erfolgreich entfernt"
#: lib/cannery_web/live/ammo_group_live/index.html.heex:10
#: lib/cannery_web/live/ammo_group_live/index.html.heex:20
#: lib/cannery_web/live/pack_live/index.html.heex:10
#: lib/cannery_web/live/pack_live/index.html.heex:20
#, elixir-autogen, elixir-format
msgid "You'll need to"
msgstr "Sie müssen"
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:78
#: lib/cannery_web/live/pack_live/form_component.html.heex:78
#, elixir-autogen, elixir-format
msgid "Creating..."
msgstr "Erstellen..."
@ -234,23 +234,23 @@ msgstr "Möchten Sie die Sprache wechseln?"
msgid "Language updated successfully."
msgstr "Spracheinstellung gespeichert."
#: lib/cannery_web/live/ammo_group_live/index.ex:89
#: lib/cannery_web/live/ammo_group_live/show.ex:55
#: lib/cannery_web/live/pack_live/index.ex:94
#: lib/cannery_web/live/pack_live/show.ex:55
#, elixir-autogen, elixir-format, fuzzy
msgid "Ammo deleted succesfully"
msgstr "Munitionsgruppe erfolgreich gelöscht"
#: lib/cannery_web/live/range_live/index.ex:93
#: lib/cannery_web/live/range_live/index.ex:92
#, elixir-autogen, elixir-format, fuzzy
msgid "Ammo unstaged succesfully"
msgstr "Munition erfolgreich demarkiert"
#: lib/cannery_web/live/ammo_group_live/form_component.ex:126
#: lib/cannery_web/live/pack_live/form_component.ex:125
#, elixir-autogen, elixir-format, fuzzy
msgid "Ammo updated successfully"
msgstr "Munitionsgruppe erfolgreich aktualisiert"
#: lib/cannery_web/live/ammo_group_live/form_component.ex:185
#: lib/cannery_web/live/pack_live/form_component.ex:184
#, elixir-autogen, elixir-format, fuzzy
msgid "Ammo added successfully"
msgid_plural "Ammo added successfully"

View File

@ -27,15 +27,15 @@ msgstr ""
#: lib/cannery_web/components/core_components/topbar.html.heex:58
#: lib/cannery_web/components/shot_group_table_component.ex:41
#: 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/pack_live/index.ex:75
#: lib/cannery_web/live/pack_live/index.ex:84
#: lib/cannery_web/live/pack_live/index.html.heex:3
#, elixir-autogen, elixir-format
msgid "Ammo"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:96
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:22
#: lib/cannery_web/components/pack_table_component.ex:95
#: lib/cannery_web/live/pack_live/form_component.html.heex:22
#, elixir-autogen, elixir-format
msgid "Ammo type"
msgstr ""
@ -86,9 +86,9 @@ msgstr ""
msgid "Case material"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:74
#: lib/cannery_web/components/move_ammo_group_component.ex:67
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:59
#: lib/cannery_web/components/move_pack_component.ex:65
#: lib/cannery_web/components/pack_table_component.ex:73
#: lib/cannery_web/live/pack_live/form_component.html.heex:59
#, elixir-autogen, elixir-format
msgid "Container"
msgstr ""
@ -107,14 +107,14 @@ msgstr ""
msgid "Corrosive"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:92
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:28
#: lib/cannery_web/components/pack_table_component.ex:91
#: lib/cannery_web/live/pack_live/form_component.html.heex:28
#, elixir-autogen, elixir-format
msgid "Count"
msgstr ""
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:16
#: lib/cannery_web/live/ammo_group_live/show.html.heex:8
#: lib/cannery_web/components/core_components/pack_card.html.heex:16
#: lib/cannery_web/live/pack_live/show.html.heex:8
#, elixir-autogen, elixir-format
msgid "Count:"
msgstr ""
@ -192,7 +192,7 @@ msgid "Keep me logged in for 60 days"
msgstr ""
#: lib/cannery_web/components/container_table_component.ex:47
#: lib/cannery_web/components/move_ammo_group_component.ex:69
#: lib/cannery_web/components/move_pack_component.ex:67
#: lib/cannery_web/live/container_live/form_component.html.heex:47
#, elixir-autogen, elixir-format
msgid "Location"
@ -258,7 +258,7 @@ msgstr ""
msgid "New Tag"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:92
#: lib/cannery_web/live/pack_live/index.html.heex:94
#, elixir-autogen, elixir-format
msgid "No Ammo"
msgstr ""
@ -288,15 +288,15 @@ msgstr ""
#: lib/cannery_web/components/add_shot_group_component.html.heex:38
#: lib/cannery_web/components/shot_group_table_component.ex:43
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:50
#: lib/cannery_web/live/ammo_group_live/show.ex:92
#: lib/cannery_web/live/pack_live/form_component.html.heex:50
#: lib/cannery_web/live/pack_live/show.ex:91
#: lib/cannery_web/live/range_live/form_component.html.heex:30
#, elixir-autogen, elixir-format
msgid "Notes"
msgstr ""
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:29
#: lib/cannery_web/live/ammo_group_live/show.html.heex:24
#: lib/cannery_web/components/core_components/pack_card.html.heex:26
#: lib/cannery_web/live/pack_live/show.html.heex:24
#, elixir-autogen, elixir-format
msgid "Notes:"
msgstr ""
@ -312,13 +312,13 @@ msgstr ""
msgid "Pressure"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:82
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:35
#: lib/cannery_web/components/pack_table_component.ex:81
#: lib/cannery_web/live/pack_live/form_component.html.heex:35
#, elixir-autogen, elixir-format
msgid "Price paid"
msgstr ""
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:44
#: lib/cannery_web/components/core_components/pack_card.html.heex:41
#, elixir-autogen, elixir-format
msgid "Price paid:"
msgstr ""
@ -360,7 +360,7 @@ msgstr ""
msgid "Steel"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.html.heex:113
#: lib/cannery_web/live/pack_live/show.html.heex:106
#, elixir-autogen, elixir-format
msgid "Stored in"
msgstr ""
@ -395,16 +395,9 @@ msgstr ""
msgid "Tracer"
msgstr ""
#: lib/cannery_web/components/ammo_type_table_component.ex:150
#: lib/cannery_web/components/container_table_component.ex:48
#: lib/cannery_web/components/move_ammo_group_component.ex:68
#: lib/cannery_web/live/ammo_group_live/index.html.heex:50
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:21
#: lib/cannery_web/live/ammo_type_live/index.html.heex:29
#: lib/cannery_web/live/ammo_type_live/show.html.heex:48
#: lib/cannery_web/components/move_pack_component.ex:66
#: lib/cannery_web/live/container_live/form_component.html.heex:39
#: lib/cannery_web/live/container_live/show.html.heex:97
#: lib/cannery_web/live/range_live/index.html.heex:86
#, elixir-autogen, elixir-format
msgid "Type"
msgstr ""
@ -435,8 +428,8 @@ msgstr ""
msgid "No tags for this container"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:78
#: lib/cannery_web/components/core_components/topbar.html.heex:66
#: lib/cannery_web/components/pack_table_component.ex:77
#, elixir-autogen, elixir-format
msgid "Range"
msgstr ""
@ -448,7 +441,7 @@ msgstr ""
#: lib/cannery_web/components/add_shot_group_component.html.heex:49
#: lib/cannery_web/components/shot_group_table_component.ex:44
#: lib/cannery_web/live/ammo_group_live/show.ex:93
#: lib/cannery_web/live/pack_live/show.ex:92
#: lib/cannery_web/live/range_live/form_component.html.heex:41
#, elixir-autogen, elixir-format
msgid "Date"
@ -465,12 +458,12 @@ 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:30
#: lib/cannery_web/live/pack_live/index.ex:35
#, elixir-autogen, elixir-format
msgid "Record shots"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.ex:42
#: lib/cannery_web/live/pack_live/show.ex:42
#: lib/cannery_web/live/range_live/index.ex:40
#, elixir-autogen, elixir-format
msgid "Edit Shot Records"
@ -494,7 +487,7 @@ msgid "Rounds left"
msgstr ""
#: lib/cannery_web/components/shot_group_table_component.ex:42
#: lib/cannery_web/live/ammo_group_live/show.ex:91
#: lib/cannery_web/live/pack_live/show.ex:90
#: lib/cannery_web/live/range_live/index.html.heex:69
#, elixir-autogen, elixir-format
msgid "Rounds shot"
@ -506,12 +499,12 @@ msgstr ""
msgid "Shot Records"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.ex:38
#: lib/cannery_web/live/pack_live/index.ex:43
#, elixir-autogen, elixir-format
msgid "Move ammo"
msgstr ""
#: lib/cannery_web/components/move_ammo_group_component.ex:85
#: lib/cannery_web/components/move_pack_component.ex:83
#, elixir-autogen, elixir-format
msgid "No other containers"
msgstr ""
@ -521,14 +514,14 @@ msgstr ""
msgid "Shot log"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:164
#: lib/cannery_web/components/ammo_group_table_component.ex:247
#: lib/cannery_web/components/ammo_type_table_component.ex:261
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:45
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:50
#: lib/cannery_web/live/ammo_group_live/show.html.heex:37
#: lib/cannery_web/live/ammo_group_live/show.html.heex:42
#: lib/cannery_web/components/core_components/pack_card.html.heex:42
#: lib/cannery_web/components/core_components/pack_card.html.heex:47
#: lib/cannery_web/components/pack_table_component.ex:163
#: lib/cannery_web/components/pack_table_component.ex:246
#: lib/cannery_web/live/ammo_type_live/show.html.heex:152
#: lib/cannery_web/live/pack_live/show.html.heex:37
#: lib/cannery_web/live/pack_live/show.html.heex:42
#, elixir-autogen, elixir-format
msgid "$%{amount}"
msgstr ""
@ -615,40 +608,40 @@ msgstr ""
msgid "Rounds:"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:161
#: lib/cannery_web/components/ammo_group_table_component.ex:243
#: lib/cannery_web/components/ammo_type_table_component.ex:260
#: lib/cannery_web/components/pack_table_component.ex:160
#: lib/cannery_web/components/pack_table_component.ex:242
#: lib/cannery_web/live/ammo_type_live/show.html.heex:156
#, elixir-autogen, elixir-format
msgid "No cost information"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:84
#: lib/cannery_web/components/pack_table_component.ex:83
#, elixir-autogen, elixir-format
msgid "% left"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.html.heex:41
#: lib/cannery_web/live/pack_live/show.html.heex:41
#, elixir-autogen, elixir-format
msgid "Current value:"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.html.heex:36
#: lib/cannery_web/live/pack_live/show.html.heex:36
#, elixir-autogen, elixir-format
msgid "Original cost:"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.html.heex:13
#: lib/cannery_web/live/pack_live/show.html.heex:13
#, elixir-autogen, elixir-format
msgid "Original count:"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.html.heex:18
#: lib/cannery_web/live/pack_live/show.html.heex:18
#, elixir-autogen, elixir-format
msgid "Percentage left:"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.html.heex:126
#: lib/cannery_web/live/pack_live/show.html.heex:119
#, elixir-autogen, elixir-format
msgid "Rounds used"
msgstr ""
@ -678,13 +671,13 @@ msgstr ""
msgid "Reset your password"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.ex:41
#: lib/cannery_web/live/pack_live/show.ex:41
#: lib/cannery_web/live/range_live/index.ex:32
#, elixir-autogen, elixir-format
msgid "Record Shots"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:69
#: lib/cannery_web/live/pack_live/form_component.html.heex:69
#, elixir-autogen, elixir-format
msgid "Copies"
msgstr ""
@ -743,12 +736,12 @@ msgstr ""
msgid "Catalog"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.ex:45
#: lib/cannery_web/live/pack_live/show.ex:45
#, elixir-autogen, elixir-format
msgid "Edit Ammo"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.ex:43
#: lib/cannery_web/live/pack_live/show.ex:43
#, elixir-autogen, elixir-format
msgid "Move Ammo"
msgstr ""
@ -758,12 +751,12 @@ msgstr ""
msgid "No ammo in this container"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.ex:44
#: lib/cannery_web/live/pack_live/show.ex:44
#, elixir-autogen, elixir-format
msgid "Show Ammo"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.html.heex:118
#: lib/cannery_web/live/pack_live/show.html.heex:111
#, elixir-autogen, elixir-format
msgid "This ammo is not in a container"
msgstr ""
@ -791,25 +784,25 @@ msgstr ""
msgid "Leave \"Uses left\" blank to make invite unlimited"
msgstr ""
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:54
#: lib/cannery_web/components/core_components/pack_card.html.heex:51
#, elixir-autogen, elixir-format
msgid "Container:"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:85
#: lib/cannery_web/live/ammo_type_live/index.html.heex:64
#: lib/cannery_web/live/ammo_type_live/show.html.heex:166
#: lib/cannery_web/live/pack_live/index.html.heex:87
#, elixir-autogen, elixir-format
msgid "Show used"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:202
#: lib/cannery_web/live/ammo_group_live/show.html.heex:19
#: lib/cannery_web/components/pack_table_component.ex:201
#: lib/cannery_web/live/pack_live/show.html.heex:19
#, elixir-autogen, elixir-format
msgid "%{percentage}%"
msgstr ""
#: lib/cannery_web/live/range_live/index.ex:153
#: lib/cannery_web/live/range_live/index.ex:154
#, elixir-autogen, elixir-format
msgid "Rounds shot: %{count}"
msgstr ""
@ -990,28 +983,28 @@ msgstr ""
msgid "Edit %{ammo_type_name}"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:251
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:17
#: lib/cannery_web/components/core_components/pack_card.html.heex:17
#: lib/cannery_web/components/pack_table_component.ex:250
#, elixir-autogen, elixir-format
msgid "Empty"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:81
#: lib/cannery_web/components/pack_table_component.ex:80
#, elixir-autogen, elixir-format
msgid "CPR"
msgstr ""
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:49
#: lib/cannery_web/components/core_components/pack_card.html.heex:46
#, elixir-autogen, elixir-format
msgid "CPR:"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:88
#: lib/cannery_web/components/pack_table_component.ex:87
#, elixir-autogen, elixir-format
msgid "Original Count"
msgstr ""
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:24
#: lib/cannery_web/components/core_components/pack_card.html.heex:21
#, elixir-autogen, elixir-format
msgid "Original Count:"
msgstr ""
@ -1021,34 +1014,34 @@ msgstr ""
msgid "Home"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:64
#: lib/cannery_web/components/pack_table_component.ex:63
#, elixir-autogen, elixir-format
msgid "Last used on"
msgstr ""
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:39
#: lib/cannery_web/components/core_components/pack_card.html.heex:36
#, elixir-autogen, elixir-format
msgid "Last used on:"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:182
#: lib/cannery_web/components/pack_table_component.ex:181
#, elixir-autogen, elixir-format
msgid "Never used"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:69
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:42
#: lib/cannery_web/components/pack_table_component.ex:68
#: lib/cannery_web/live/pack_live/form_component.html.heex:42
#, elixir-autogen, elixir-format
msgid "Purchased on"
msgstr ""
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:34
#: lib/cannery_web/live/ammo_group_live/show.html.heex:30
#: lib/cannery_web/components/core_components/pack_card.html.heex:31
#: lib/cannery_web/live/pack_live/show.html.heex:30
#, elixir-autogen, elixir-format
msgid "Purchased on:"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.ex:46
#: lib/cannery_web/live/pack_live/index.ex:51
#, elixir-autogen, elixir-format
msgid "Edit ammo"
msgstr ""
@ -1064,7 +1057,7 @@ msgstr ""
msgid "Search catalog"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:79
#: lib/cannery_web/live/pack_live/index.html.heex:81
#, elixir-autogen, elixir-format
msgid "Search ammo"
msgstr ""
@ -1208,12 +1201,12 @@ msgstr ""
msgid "Really great weather"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:60
#: lib/cannery_web/components/ammo_type_table_component.ex:100
#: lib/cannery_web/components/container_table_component.ex:67
#: lib/cannery_web/components/move_ammo_group_component.ex:70
#: lib/cannery_web/components/move_pack_component.ex:68
#: lib/cannery_web/components/pack_table_component.ex:59
#: lib/cannery_web/components/shot_group_table_component.ex:45
#: lib/cannery_web/live/ammo_group_live/show.ex:94
#: lib/cannery_web/live/pack_live/show.ex:93
#, elixir-autogen, elixir-format
msgid "Actions"
msgstr ""
@ -1228,7 +1221,7 @@ msgstr ""
msgid "Log out"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:92
#: lib/cannery_web/components/pack_table_component.ex:91
#, elixir-autogen, elixir-format
msgid "Current Count"
msgstr ""
@ -1239,9 +1232,9 @@ msgstr ""
msgid "Close modal"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:56
#: lib/cannery_web/live/ammo_type_live/index.html.heex:35
#: lib/cannery_web/live/container_live/show.html.heex:103
#: lib/cannery_web/live/pack_live/index.html.heex:58
#: lib/cannery_web/live/range_live/index.html.heex:92
#, elixir-autogen, elixir-format
msgid "All"
@ -1313,7 +1306,7 @@ msgstr ""
msgid "Load grains:"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:29
#: lib/cannery_web/live/pack_live/index.html.heex:29
#, elixir-autogen, elixir-format
msgid "No ammo"
msgstr ""
@ -1323,11 +1316,11 @@ msgstr ""
msgid "None specified"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:59
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:25
#: lib/cannery_web/live/ammo_type_live/index.html.heex:38
#: lib/cannery_web/live/ammo_type_live/show.html.heex:58
#: lib/cannery_web/live/container_live/show.html.heex:106
#: lib/cannery_web/live/pack_live/index.html.heex:61
#: lib/cannery_web/live/range_live/index.html.heex:95
#, elixir-autogen, elixir-format
msgid "Pistol"
@ -1348,11 +1341,11 @@ msgstr ""
msgid "Projectile"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:57
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:25
#: lib/cannery_web/live/ammo_type_live/index.html.heex:36
#: lib/cannery_web/live/ammo_type_live/show.html.heex:56
#: lib/cannery_web/live/container_live/show.html.heex:104
#: lib/cannery_web/live/pack_live/index.html.heex:59
#: lib/cannery_web/live/range_live/index.html.heex:93
#, elixir-autogen, elixir-format
msgid "Rifle"
@ -1402,11 +1395,11 @@ msgstr ""
msgid "Shot type:"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:58
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:25
#: lib/cannery_web/live/ammo_type_live/index.html.heex:37
#: lib/cannery_web/live/ammo_type_live/show.html.heex:54
#: lib/cannery_web/live/container_live/show.html.heex:105
#: lib/cannery_web/live/pack_live/index.html.heex:60
#: lib/cannery_web/live/range_live/index.html.heex:94
#, elixir-autogen, elixir-format
msgid "Shotgun"
@ -1444,3 +1437,14 @@ msgstr ""
#, elixir-autogen, elixir-format
msgid "Wadding:"
msgstr ""
#: lib/cannery_web/components/ammo_type_table_component.ex:150
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:21
#: lib/cannery_web/live/ammo_type_live/index.html.heex:29
#: lib/cannery_web/live/ammo_type_live/show.html.heex:48
#: lib/cannery_web/live/container_live/show.html.heex:97
#: lib/cannery_web/live/pack_live/index.html.heex:50
#: lib/cannery_web/live/range_live/index.html.heex:86
#, elixir-autogen, elixir-format
msgid "Class"
msgstr ""

View File

@ -10,14 +10,14 @@ msgid ""
msgstr ""
"Language: en\n"
#: 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:38
#: lib/cannery_web/live/pack_live/index.ex:59
#: lib/cannery_web/live/pack_live/index.ex:67
#: lib/cannery_web/live/pack_live/index.html.heex:38
#, elixir-autogen, elixir-format
msgid "Add Ammo"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:34
#: lib/cannery_web/live/pack_live/index.html.heex:34
#, elixir-autogen, elixir-format
msgid "Add your first box!"
msgstr ""
@ -121,10 +121,10 @@ msgid "Reset password"
msgstr ""
#: lib/cannery_web/components/add_shot_group_component.html.heex:57
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:84
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:350
#: lib/cannery_web/live/container_live/form_component.html.heex:57
#: lib/cannery_web/live/invite_live/form_component.html.heex:35
#: lib/cannery_web/live/pack_live/form_component.html.heex:84
#: lib/cannery_web/live/range_live/form_component.html.heex:45
#: lib/cannery_web/live/tag_live/form_component.html.heex:37
#, elixir-autogen, elixir-format
@ -156,19 +156,19 @@ msgstr ""
msgid "Why not get some ready to shoot?"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:125
#: lib/cannery_web/live/ammo_group_live/show.html.heex:103
#: lib/cannery_web/live/pack_live/index.html.heex:127
#: lib/cannery_web/live/pack_live/show.html.heex:96
#: lib/cannery_web/live/range_live/index.html.heex:45
#, elixir-autogen, elixir-format
msgid "Record shots"
msgstr ""
#: lib/cannery_web/components/move_ammo_group_component.ex:90
#: lib/cannery_web/components/move_pack_component.ex:88
#, elixir-autogen, elixir-format
msgid "Add another container!"
msgstr ""
#: lib/cannery_web/components/move_ammo_group_component.ex:126
#: lib/cannery_web/components/move_pack_component.ex:124
#, elixir-autogen, elixir-format
msgid "Select"
msgstr ""
@ -178,12 +178,12 @@ msgstr ""
msgid "Copy to clipboard"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:14
#: lib/cannery_web/live/pack_live/index.html.heex:14
#, elixir-autogen, elixir-format
msgid "add a container first"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:77
#: lib/cannery_web/live/pack_live/form_component.html.heex:77
#, elixir-autogen, elixir-format, fuzzy
msgid "Create"
msgstr ""
@ -198,19 +198,19 @@ msgstr ""
msgid "Change language"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.html.heex:55
#: lib/cannery_web/live/pack_live/show.html.heex:55
#, elixir-autogen, elixir-format
msgid "View in Catalog"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:24
#: lib/cannery_web/live/pack_live/index.html.heex:24
#, elixir-autogen, elixir-format
msgid "add an ammo type first"
msgstr ""
#: lib/cannery_web/components/move_ammo_group_component.ex:80
#: lib/cannery_web/live/ammo_group_live/index.html.heex:142
#: lib/cannery_web/live/ammo_group_live/show.html.heex:96
#: lib/cannery_web/components/move_pack_component.ex:78
#: lib/cannery_web/live/pack_live/index.html.heex:144
#: lib/cannery_web/live/pack_live/show.html.heex:89
#, elixir-autogen, elixir-format
msgid "Move ammo"
msgstr ""
@ -220,13 +220,13 @@ msgstr ""
msgid "Set Unlimited"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.html.heex:89
#: lib/cannery_web/live/pack_live/show.html.heex:85
#: lib/cannery_web/live/range_live/index.html.heex:38
#, elixir-autogen, elixir-format
msgid "Stage for range"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.html.heex:88
#: lib/cannery_web/live/pack_live/show.html.heex:84
#: lib/cannery_web/live/range_live/index.html.heex:37
#, elixir-autogen, elixir-format
msgid "Unstage from range"
@ -276,7 +276,7 @@ msgstr ""
msgid "Delete invite for %{invite_name}"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.ex:161
#: lib/cannery_web/live/pack_live/show.ex:160
#: lib/cannery_web/live/range_live/index.html.heex:155
#, elixir-autogen, elixir-format
msgid "Delete shot record of %{shot_group_count} shots"
@ -300,18 +300,12 @@ msgstr ""
msgid "Edit %{tag_name}"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:164
#: lib/cannery_web/live/ammo_group_live/show.html.heex:62
#, elixir-autogen, elixir-format
msgid "Edit ammo group of %{ammo_group_count} bullets"
msgstr ""
#: lib/cannery_web/live/invite_live/index.html.heex:46
#, elixir-autogen, elixir-format
msgid "Edit invite for %{invite_name}"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.ex:146
#: lib/cannery_web/live/pack_live/show.ex:145
#, elixir-autogen, elixir-format
msgid "Edit shot group of %{shot_group_count} shots"
msgstr ""
@ -321,7 +315,7 @@ msgstr ""
msgid "Edit shot record of %{shot_group_count} shots"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:118
#: lib/cannery_web/live/pack_live/index.html.heex:120
#, elixir-autogen, elixir-format, fuzzy
msgid "Stage"
msgstr ""
@ -332,7 +326,7 @@ msgstr ""
msgid "Tag %{container_name}"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:117
#: lib/cannery_web/live/pack_live/index.html.heex:119
#, elixir-autogen, elixir-format
msgid "Unstage"
msgstr ""
@ -342,19 +336,25 @@ msgstr ""
msgid "View %{ammo_type_name}"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:176
#: lib/cannery_web/live/pack_live/index.html.heex:174
#, elixir-autogen, elixir-format, fuzzy
msgid "Clone ammo group of %{ammo_group_count} bullets"
msgid "Clone pack of %{pack_count} bullets"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:191
#: lib/cannery_web/live/ammo_group_live/show.html.heex:76
#: lib/cannery_web/live/pack_live/index.html.heex:189
#: lib/cannery_web/live/pack_live/show.html.heex:74
#, elixir-autogen, elixir-format, fuzzy
msgid "Delete ammo group of %{ammo_group_count} bullets"
msgid "Delete pack of %{pack_count} bullets"
msgstr ""
#: lib/cannery_web/live/pack_live/index.html.heex:164
#: lib/cannery_web/live/pack_live/show.html.heex:62
#, elixir-autogen, elixir-format, fuzzy
msgid "Edit pack of %{pack_count} bullets"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:152
#: lib/cannery_web/live/ammo_type_live/show.html.heex:206
#: lib/cannery_web/live/pack_live/index.html.heex:154
#, elixir-autogen, elixir-format, fuzzy
msgid "View ammo group of %{ammo_group_count} bullets"
msgid "View pack of %{pack_count} bullets"
msgstr ""

View File

@ -27,15 +27,15 @@ msgstr ""
#: lib/cannery_web/components/core_components/topbar.html.heex:58
#: lib/cannery_web/components/shot_group_table_component.ex:41
#: 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/pack_live/index.ex:75
#: lib/cannery_web/live/pack_live/index.ex:84
#: lib/cannery_web/live/pack_live/index.html.heex:3
#, elixir-autogen, elixir-format
msgid "Ammo"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:96
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:22
#: lib/cannery_web/components/pack_table_component.ex:95
#: lib/cannery_web/live/pack_live/form_component.html.heex:22
#, elixir-autogen, elixir-format
msgid "Ammo type"
msgstr ""
@ -86,9 +86,9 @@ msgstr ""
msgid "Case material"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:74
#: lib/cannery_web/components/move_ammo_group_component.ex:67
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:59
#: lib/cannery_web/components/move_pack_component.ex:65
#: lib/cannery_web/components/pack_table_component.ex:73
#: lib/cannery_web/live/pack_live/form_component.html.heex:59
#, elixir-autogen, elixir-format
msgid "Container"
msgstr ""
@ -107,14 +107,14 @@ msgstr ""
msgid "Corrosive"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:92
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:28
#: lib/cannery_web/components/pack_table_component.ex:91
#: lib/cannery_web/live/pack_live/form_component.html.heex:28
#, elixir-autogen, elixir-format
msgid "Count"
msgstr ""
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:16
#: lib/cannery_web/live/ammo_group_live/show.html.heex:8
#: lib/cannery_web/components/core_components/pack_card.html.heex:16
#: lib/cannery_web/live/pack_live/show.html.heex:8
#, elixir-autogen, elixir-format
msgid "Count:"
msgstr ""
@ -192,7 +192,7 @@ msgid "Keep me logged in for 60 days"
msgstr ""
#: lib/cannery_web/components/container_table_component.ex:47
#: lib/cannery_web/components/move_ammo_group_component.ex:69
#: lib/cannery_web/components/move_pack_component.ex:67
#: lib/cannery_web/live/container_live/form_component.html.heex:47
#, elixir-autogen, elixir-format
msgid "Location"
@ -258,7 +258,7 @@ msgstr ""
msgid "New Tag"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:92
#: lib/cannery_web/live/pack_live/index.html.heex:94
#, elixir-autogen, elixir-format
msgid "No Ammo"
msgstr ""
@ -288,15 +288,15 @@ msgstr ""
#: lib/cannery_web/components/add_shot_group_component.html.heex:38
#: lib/cannery_web/components/shot_group_table_component.ex:43
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:50
#: lib/cannery_web/live/ammo_group_live/show.ex:92
#: lib/cannery_web/live/pack_live/form_component.html.heex:50
#: lib/cannery_web/live/pack_live/show.ex:91
#: lib/cannery_web/live/range_live/form_component.html.heex:30
#, elixir-autogen, elixir-format
msgid "Notes"
msgstr ""
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:29
#: lib/cannery_web/live/ammo_group_live/show.html.heex:24
#: lib/cannery_web/components/core_components/pack_card.html.heex:26
#: lib/cannery_web/live/pack_live/show.html.heex:24
#, elixir-autogen, elixir-format
msgid "Notes:"
msgstr ""
@ -312,13 +312,13 @@ msgstr ""
msgid "Pressure"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:82
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:35
#: lib/cannery_web/components/pack_table_component.ex:81
#: lib/cannery_web/live/pack_live/form_component.html.heex:35
#, elixir-autogen, elixir-format
msgid "Price paid"
msgstr ""
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:44
#: lib/cannery_web/components/core_components/pack_card.html.heex:41
#, elixir-autogen, elixir-format
msgid "Price paid:"
msgstr ""
@ -360,7 +360,7 @@ msgstr ""
msgid "Steel"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.html.heex:113
#: lib/cannery_web/live/pack_live/show.html.heex:106
#, elixir-autogen, elixir-format
msgid "Stored in"
msgstr ""
@ -395,16 +395,9 @@ msgstr ""
msgid "Tracer"
msgstr ""
#: lib/cannery_web/components/ammo_type_table_component.ex:150
#: lib/cannery_web/components/container_table_component.ex:48
#: lib/cannery_web/components/move_ammo_group_component.ex:68
#: lib/cannery_web/live/ammo_group_live/index.html.heex:50
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:21
#: lib/cannery_web/live/ammo_type_live/index.html.heex:29
#: lib/cannery_web/live/ammo_type_live/show.html.heex:48
#: lib/cannery_web/components/move_pack_component.ex:66
#: lib/cannery_web/live/container_live/form_component.html.heex:39
#: lib/cannery_web/live/container_live/show.html.heex:97
#: lib/cannery_web/live/range_live/index.html.heex:86
#, elixir-autogen, elixir-format
msgid "Type"
msgstr ""
@ -435,8 +428,8 @@ msgstr ""
msgid "No tags for this container"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:78
#: lib/cannery_web/components/core_components/topbar.html.heex:66
#: lib/cannery_web/components/pack_table_component.ex:77
#, elixir-autogen, elixir-format
msgid "Range"
msgstr ""
@ -448,7 +441,7 @@ msgstr ""
#: lib/cannery_web/components/add_shot_group_component.html.heex:49
#: lib/cannery_web/components/shot_group_table_component.ex:44
#: lib/cannery_web/live/ammo_group_live/show.ex:93
#: lib/cannery_web/live/pack_live/show.ex:92
#: lib/cannery_web/live/range_live/form_component.html.heex:41
#, elixir-autogen, elixir-format
msgid "Date"
@ -465,12 +458,12 @@ 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:30
#: lib/cannery_web/live/pack_live/index.ex:35
#, elixir-autogen, elixir-format
msgid "Record shots"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.ex:42
#: lib/cannery_web/live/pack_live/show.ex:42
#: lib/cannery_web/live/range_live/index.ex:40
#, elixir-autogen, elixir-format
msgid "Edit Shot Records"
@ -494,7 +487,7 @@ msgid "Rounds left"
msgstr ""
#: lib/cannery_web/components/shot_group_table_component.ex:42
#: lib/cannery_web/live/ammo_group_live/show.ex:91
#: lib/cannery_web/live/pack_live/show.ex:90
#: lib/cannery_web/live/range_live/index.html.heex:69
#, elixir-autogen, elixir-format
msgid "Rounds shot"
@ -506,12 +499,12 @@ msgstr ""
msgid "Shot Records"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.ex:38
#: lib/cannery_web/live/pack_live/index.ex:43
#, elixir-autogen, elixir-format
msgid "Move ammo"
msgstr ""
#: lib/cannery_web/components/move_ammo_group_component.ex:85
#: lib/cannery_web/components/move_pack_component.ex:83
#, elixir-autogen, elixir-format
msgid "No other containers"
msgstr ""
@ -521,14 +514,14 @@ msgstr ""
msgid "Shot log"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:164
#: lib/cannery_web/components/ammo_group_table_component.ex:247
#: lib/cannery_web/components/ammo_type_table_component.ex:261
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:45
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:50
#: lib/cannery_web/live/ammo_group_live/show.html.heex:37
#: lib/cannery_web/live/ammo_group_live/show.html.heex:42
#: lib/cannery_web/components/core_components/pack_card.html.heex:42
#: lib/cannery_web/components/core_components/pack_card.html.heex:47
#: lib/cannery_web/components/pack_table_component.ex:163
#: lib/cannery_web/components/pack_table_component.ex:246
#: lib/cannery_web/live/ammo_type_live/show.html.heex:152
#: lib/cannery_web/live/pack_live/show.html.heex:37
#: lib/cannery_web/live/pack_live/show.html.heex:42
#, elixir-autogen, elixir-format
msgid "$%{amount}"
msgstr ""
@ -615,40 +608,40 @@ msgstr ""
msgid "Rounds:"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:161
#: lib/cannery_web/components/ammo_group_table_component.ex:243
#: lib/cannery_web/components/ammo_type_table_component.ex:260
#: lib/cannery_web/components/pack_table_component.ex:160
#: lib/cannery_web/components/pack_table_component.ex:242
#: lib/cannery_web/live/ammo_type_live/show.html.heex:156
#, elixir-autogen, elixir-format
msgid "No cost information"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:84
#: lib/cannery_web/components/pack_table_component.ex:83
#, elixir-autogen, elixir-format
msgid "% left"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.html.heex:41
#: lib/cannery_web/live/pack_live/show.html.heex:41
#, elixir-autogen, elixir-format
msgid "Current value:"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.html.heex:36
#: lib/cannery_web/live/pack_live/show.html.heex:36
#, elixir-autogen, elixir-format
msgid "Original cost:"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.html.heex:13
#: lib/cannery_web/live/pack_live/show.html.heex:13
#, elixir-autogen, elixir-format
msgid "Original count:"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.html.heex:18
#: lib/cannery_web/live/pack_live/show.html.heex:18
#, elixir-autogen, elixir-format
msgid "Percentage left:"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.html.heex:126
#: lib/cannery_web/live/pack_live/show.html.heex:119
#, elixir-autogen, elixir-format, fuzzy
msgid "Rounds used"
msgstr ""
@ -678,13 +671,13 @@ msgstr ""
msgid "Reset your password"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.ex:41
#: lib/cannery_web/live/pack_live/show.ex:41
#: lib/cannery_web/live/range_live/index.ex:32
#, elixir-autogen, elixir-format, fuzzy
msgid "Record Shots"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:69
#: lib/cannery_web/live/pack_live/form_component.html.heex:69
#, elixir-autogen, elixir-format
msgid "Copies"
msgstr ""
@ -743,12 +736,12 @@ msgstr ""
msgid "Catalog"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.ex:45
#: lib/cannery_web/live/pack_live/show.ex:45
#, elixir-autogen, elixir-format, fuzzy
msgid "Edit Ammo"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.ex:43
#: lib/cannery_web/live/pack_live/show.ex:43
#, elixir-autogen, elixir-format, fuzzy
msgid "Move Ammo"
msgstr ""
@ -758,12 +751,12 @@ msgstr ""
msgid "No ammo in this container"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.ex:44
#: lib/cannery_web/live/pack_live/show.ex:44
#, elixir-autogen, elixir-format, fuzzy
msgid "Show Ammo"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.html.heex:118
#: lib/cannery_web/live/pack_live/show.html.heex:111
#, elixir-autogen, elixir-format, fuzzy
msgid "This ammo is not in a container"
msgstr ""
@ -791,25 +784,25 @@ msgstr ""
msgid "Leave \"Uses left\" blank to make invite unlimited"
msgstr ""
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:54
#: lib/cannery_web/components/core_components/pack_card.html.heex:51
#, elixir-autogen, elixir-format, fuzzy
msgid "Container:"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:85
#: lib/cannery_web/live/ammo_type_live/index.html.heex:64
#: lib/cannery_web/live/ammo_type_live/show.html.heex:166
#: lib/cannery_web/live/pack_live/index.html.heex:87
#, elixir-autogen, elixir-format
msgid "Show used"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:202
#: lib/cannery_web/live/ammo_group_live/show.html.heex:19
#: lib/cannery_web/components/pack_table_component.ex:201
#: lib/cannery_web/live/pack_live/show.html.heex:19
#, elixir-autogen, elixir-format
msgid "%{percentage}%"
msgstr ""
#: lib/cannery_web/live/range_live/index.ex:153
#: lib/cannery_web/live/range_live/index.ex:154
#, elixir-autogen, elixir-format, fuzzy
msgid "Rounds shot: %{count}"
msgstr ""
@ -990,28 +983,28 @@ msgstr ""
msgid "Edit %{ammo_type_name}"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:251
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:17
#: lib/cannery_web/components/core_components/pack_card.html.heex:17
#: lib/cannery_web/components/pack_table_component.ex:250
#, elixir-autogen, elixir-format
msgid "Empty"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:81
#: lib/cannery_web/components/pack_table_component.ex:80
#, elixir-autogen, elixir-format
msgid "CPR"
msgstr ""
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:49
#: lib/cannery_web/components/core_components/pack_card.html.heex:46
#, elixir-autogen, elixir-format
msgid "CPR:"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:88
#: lib/cannery_web/components/pack_table_component.ex:87
#, elixir-autogen, elixir-format, fuzzy
msgid "Original Count"
msgstr ""
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:24
#: lib/cannery_web/components/core_components/pack_card.html.heex:21
#, elixir-autogen, elixir-format, fuzzy
msgid "Original Count:"
msgstr ""
@ -1021,34 +1014,34 @@ msgstr ""
msgid "Home"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:64
#: lib/cannery_web/components/pack_table_component.ex:63
#, elixir-autogen, elixir-format
msgid "Last used on"
msgstr ""
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:39
#: lib/cannery_web/components/core_components/pack_card.html.heex:36
#, elixir-autogen, elixir-format
msgid "Last used on:"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:182
#: lib/cannery_web/components/pack_table_component.ex:181
#, elixir-autogen, elixir-format
msgid "Never used"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:69
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:42
#: lib/cannery_web/components/pack_table_component.ex:68
#: lib/cannery_web/live/pack_live/form_component.html.heex:42
#, elixir-autogen, elixir-format
msgid "Purchased on"
msgstr ""
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:34
#: lib/cannery_web/live/ammo_group_live/show.html.heex:30
#: lib/cannery_web/components/core_components/pack_card.html.heex:31
#: lib/cannery_web/live/pack_live/show.html.heex:30
#, elixir-autogen, elixir-format
msgid "Purchased on:"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.ex:46
#: lib/cannery_web/live/pack_live/index.ex:51
#, elixir-autogen, elixir-format, fuzzy
msgid "Edit ammo"
msgstr ""
@ -1064,7 +1057,7 @@ msgstr ""
msgid "Search catalog"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:79
#: lib/cannery_web/live/pack_live/index.html.heex:81
#, elixir-autogen, elixir-format, fuzzy
msgid "Search ammo"
msgstr ""
@ -1208,12 +1201,12 @@ msgstr ""
msgid "Really great weather"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:60
#: lib/cannery_web/components/ammo_type_table_component.ex:100
#: lib/cannery_web/components/container_table_component.ex:67
#: lib/cannery_web/components/move_ammo_group_component.ex:70
#: lib/cannery_web/components/move_pack_component.ex:68
#: lib/cannery_web/components/pack_table_component.ex:59
#: lib/cannery_web/components/shot_group_table_component.ex:45
#: lib/cannery_web/live/ammo_group_live/show.ex:94
#: lib/cannery_web/live/pack_live/show.ex:93
#, elixir-autogen, elixir-format
msgid "Actions"
msgstr ""
@ -1228,7 +1221,7 @@ msgstr ""
msgid "Log out"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:92
#: lib/cannery_web/components/pack_table_component.ex:91
#, elixir-autogen, elixir-format
msgid "Current Count"
msgstr ""
@ -1239,9 +1232,9 @@ msgstr ""
msgid "Close modal"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:56
#: lib/cannery_web/live/ammo_type_live/index.html.heex:35
#: lib/cannery_web/live/container_live/show.html.heex:103
#: lib/cannery_web/live/pack_live/index.html.heex:58
#: lib/cannery_web/live/range_live/index.html.heex:92
#, elixir-autogen, elixir-format
msgid "All"
@ -1313,7 +1306,7 @@ msgstr ""
msgid "Load grains:"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:29
#: lib/cannery_web/live/pack_live/index.html.heex:29
#, elixir-autogen, elixir-format, fuzzy
msgid "No ammo"
msgstr ""
@ -1323,11 +1316,11 @@ msgstr ""
msgid "None specified"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:59
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:25
#: lib/cannery_web/live/ammo_type_live/index.html.heex:38
#: lib/cannery_web/live/ammo_type_live/show.html.heex:58
#: lib/cannery_web/live/container_live/show.html.heex:106
#: lib/cannery_web/live/pack_live/index.html.heex:61
#: lib/cannery_web/live/range_live/index.html.heex:95
#, elixir-autogen, elixir-format
msgid "Pistol"
@ -1348,11 +1341,11 @@ msgstr ""
msgid "Projectile"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:57
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:25
#: lib/cannery_web/live/ammo_type_live/index.html.heex:36
#: lib/cannery_web/live/ammo_type_live/show.html.heex:56
#: lib/cannery_web/live/container_live/show.html.heex:104
#: lib/cannery_web/live/pack_live/index.html.heex:59
#: lib/cannery_web/live/range_live/index.html.heex:93
#, elixir-autogen, elixir-format
msgid "Rifle"
@ -1402,11 +1395,11 @@ msgstr ""
msgid "Shot type:"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:58
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:25
#: lib/cannery_web/live/ammo_type_live/index.html.heex:37
#: lib/cannery_web/live/ammo_type_live/show.html.heex:54
#: lib/cannery_web/live/container_live/show.html.heex:105
#: lib/cannery_web/live/pack_live/index.html.heex:60
#: lib/cannery_web/live/range_live/index.html.heex:94
#, elixir-autogen, elixir-format
msgid "Shotgun"
@ -1444,3 +1437,14 @@ msgstr ""
#, elixir-autogen, elixir-format
msgid "Wadding:"
msgstr ""
#: lib/cannery_web/components/ammo_type_table_component.ex:150
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:21
#: lib/cannery_web/live/ammo_type_live/index.html.heex:29
#: lib/cannery_web/live/ammo_type_live/show.html.heex:48
#: lib/cannery_web/live/container_live/show.html.heex:97
#: lib/cannery_web/live/pack_live/index.html.heex:50
#: lib/cannery_web/live/range_live/index.html.heex:86
#, elixir-autogen, elixir-format
msgid "Class"
msgstr ""

View File

@ -146,22 +146,22 @@ msgstr ""
msgid "Tag could not be removed"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/form_component.ex:160
#: lib/cannery_web/live/pack_live/form_component.ex:159
#, elixir-autogen, elixir-format
msgid "Could not parse number of copies"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/form_component.ex:150
#: lib/cannery_web/live/pack_live/form_component.ex:149
#, elixir-autogen, elixir-format
msgid "Invalid number of copies, must be between 1 and %{max}. Was %{multiplier}"
msgstr ""
#: lib/cannery/ammo.ex:1114
#: lib/cannery/ammo.ex:1123
#, elixir-autogen, elixir-format
msgid "Invalid multiplier"
msgstr ""
#: lib/cannery/ammo/ammo_group.ex:92
#: lib/cannery/ammo/pack.ex:92
#, elixir-autogen, elixir-format
msgid "Please select an ammo type and container"
msgstr ""
@ -186,7 +186,7 @@ msgstr ""
msgid "Ammo left must be at least 0"
msgstr ""
#: lib/cannery/activity_log/shot_group.ex:122
#: lib/cannery/activity_log/shot_group.ex:119
#, elixir-autogen, elixir-format, fuzzy
msgid "Count can be at most %{count} shots"
msgstr ""

View File

@ -58,8 +58,8 @@ msgstr ""
msgid "Are you sure you want to delete %{name}?"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:189
#: lib/cannery_web/live/ammo_group_live/show.html.heex:74
#: lib/cannery_web/live/pack_live/index.html.heex:187
#: lib/cannery_web/live/pack_live/show.html.heex:72
#, elixir-autogen, elixir-format
msgid "Are you sure you want to delete this ammo?"
msgstr ""
@ -110,10 +110,10 @@ msgid "Please check your email to verify your account"
msgstr ""
#: lib/cannery_web/components/add_shot_group_component.html.heex:59
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:85
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:351
#: lib/cannery_web/live/container_live/form_component.html.heex:59
#: lib/cannery_web/live/invite_live/form_component.html.heex:37
#: lib/cannery_web/live/pack_live/form_component.html.heex:85
#: lib/cannery_web/live/range_live/form_component.html.heex:47
#: lib/cannery_web/live/tag_live/form_component.html.heex:39
#, elixir-autogen, elixir-format
@ -155,13 +155,13 @@ msgstr ""
msgid "Are you sure you want to unstage this ammo?"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.ex:159
#: lib/cannery_web/live/pack_live/show.ex:158
#: lib/cannery_web/live/range_live/index.html.heex:152
#, elixir-autogen, elixir-format
msgid "Are you sure you want to delete this shot record?"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.ex:81
#: lib/cannery_web/live/pack_live/show.ex:80
#: lib/cannery_web/live/range_live/index.ex:79
#, elixir-autogen, elixir-format
msgid "Shot records deleted succesfully"
@ -177,7 +177,7 @@ msgstr ""
msgid "%{email} confirmed successfully."
msgstr ""
#: lib/cannery_web/components/move_ammo_group_component.ex:54
#: lib/cannery_web/components/move_pack_component.ex:52
#, elixir-autogen, elixir-format
msgid "Ammo moved to %{name} successfully"
msgstr ""
@ -192,13 +192,13 @@ msgstr ""
msgid "%{name} removed successfully"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:10
#: lib/cannery_web/live/ammo_group_live/index.html.heex:20
#: lib/cannery_web/live/pack_live/index.html.heex:10
#: lib/cannery_web/live/pack_live/index.html.heex:20
#, elixir-autogen, elixir-format
msgid "You'll need to"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:78
#: lib/cannery_web/live/pack_live/form_component.html.heex:78
#, elixir-autogen, elixir-format, fuzzy
msgid "Creating..."
msgstr ""
@ -213,23 +213,23 @@ msgstr ""
msgid "Language updated successfully."
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.ex:89
#: lib/cannery_web/live/ammo_group_live/show.ex:55
#: lib/cannery_web/live/pack_live/index.ex:94
#: lib/cannery_web/live/pack_live/show.ex:55
#, elixir-autogen, elixir-format, fuzzy
msgid "Ammo deleted succesfully"
msgstr ""
#: lib/cannery_web/live/range_live/index.ex:93
#: lib/cannery_web/live/range_live/index.ex:92
#, elixir-autogen, elixir-format, fuzzy
msgid "Ammo unstaged succesfully"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/form_component.ex:126
#: lib/cannery_web/live/pack_live/form_component.ex:125
#, elixir-autogen, elixir-format, fuzzy
msgid "Ammo updated successfully"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/form_component.ex:185
#: lib/cannery_web/live/pack_live/form_component.ex:184
#, elixir-autogen, elixir-format, fuzzy
msgid "Ammo added successfully"
msgid_plural "Ammo added successfully"

View File

@ -145,22 +145,22 @@ msgstr ""
msgid "Tag could not be removed"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/form_component.ex:160
#: lib/cannery_web/live/pack_live/form_component.ex:159
#, elixir-autogen, elixir-format
msgid "Could not parse number of copies"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/form_component.ex:150
#: lib/cannery_web/live/pack_live/form_component.ex:149
#, elixir-autogen, elixir-format
msgid "Invalid number of copies, must be between 1 and %{max}. Was %{multiplier}"
msgstr ""
#: lib/cannery/ammo.ex:1114
#: lib/cannery/ammo.ex:1123
#, elixir-autogen, elixir-format
msgid "Invalid multiplier"
msgstr ""
#: lib/cannery/ammo/ammo_group.ex:92
#: lib/cannery/ammo/pack.ex:92
#, elixir-autogen, elixir-format
msgid "Please select an ammo type and container"
msgstr ""
@ -185,7 +185,7 @@ msgstr ""
msgid "Ammo left must be at least 0"
msgstr ""
#: lib/cannery/activity_log/shot_group.ex:122
#: lib/cannery/activity_log/shot_group.ex:119
#, elixir-autogen, elixir-format
msgid "Count can be at most %{count} shots"
msgstr ""

View File

@ -23,14 +23,14 @@ 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:54
#: lib/cannery_web/live/ammo_group_live/index.ex:62
#: lib/cannery_web/live/ammo_group_live/index.html.heex:38
#: lib/cannery_web/live/pack_live/index.ex:59
#: lib/cannery_web/live/pack_live/index.ex:67
#: lib/cannery_web/live/pack_live/index.html.heex:38
#, elixir-autogen, elixir-format
msgid "Add Ammo"
msgstr "Añadir Munición"
#: lib/cannery_web/live/ammo_group_live/index.html.heex:34
#: lib/cannery_web/live/pack_live/index.html.heex:34
#, elixir-autogen, elixir-format
msgid "Add your first box!"
msgstr "¡Añade tu primera caja!"
@ -134,10 +134,10 @@ msgid "Reset password"
msgstr "Resetear contraseña"
#: lib/cannery_web/components/add_shot_group_component.html.heex:57
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:84
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:350
#: lib/cannery_web/live/container_live/form_component.html.heex:57
#: lib/cannery_web/live/invite_live/form_component.html.heex:35
#: lib/cannery_web/live/pack_live/form_component.html.heex:84
#: lib/cannery_web/live/range_live/form_component.html.heex:45
#: lib/cannery_web/live/tag_live/form_component.html.heex:37
#, elixir-autogen, elixir-format
@ -169,19 +169,19 @@ 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:125
#: lib/cannery_web/live/ammo_group_live/show.html.heex:103
#: lib/cannery_web/live/pack_live/index.html.heex:127
#: lib/cannery_web/live/pack_live/show.html.heex:96
#: lib/cannery_web/live/range_live/index.html.heex:45
#, elixir-autogen, elixir-format
msgid "Record shots"
msgstr "Tiros récord"
#: lib/cannery_web/components/move_ammo_group_component.ex:90
#: lib/cannery_web/components/move_pack_component.ex:88
#, elixir-autogen, elixir-format
msgid "Add another container!"
msgstr "¡Añade otro contenedor!"
#: lib/cannery_web/components/move_ammo_group_component.ex:126
#: lib/cannery_web/components/move_pack_component.ex:124
#, elixir-autogen, elixir-format
msgid "Select"
msgstr "Seleccionar"
@ -191,12 +191,12 @@ msgstr "Seleccionar"
msgid "Copy to clipboard"
msgstr "Copiar al portapapeles"
#: lib/cannery_web/live/ammo_group_live/index.html.heex:14
#: lib/cannery_web/live/pack_live/index.html.heex:14
#, elixir-autogen, elixir-format
msgid "add a container first"
msgstr "añade primero un contenedor"
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:77
#: lib/cannery_web/live/pack_live/form_component.html.heex:77
#, elixir-autogen, elixir-format
msgid "Create"
msgstr "Crear"
@ -211,19 +211,19 @@ msgstr "Cambiar Lenguaje"
msgid "Change language"
msgstr "Cambiar lenguaje"
#: lib/cannery_web/live/ammo_group_live/show.html.heex:55
#: lib/cannery_web/live/pack_live/show.html.heex:55
#, elixir-autogen, elixir-format
msgid "View in Catalog"
msgstr "Ver en Catalogo"
#: lib/cannery_web/live/ammo_group_live/index.html.heex:24
#: lib/cannery_web/live/pack_live/index.html.heex:24
#, elixir-autogen, elixir-format
msgid "add an ammo type first"
msgstr "añade primero un tipo de munición"
#: lib/cannery_web/components/move_ammo_group_component.ex:80
#: lib/cannery_web/live/ammo_group_live/index.html.heex:142
#: lib/cannery_web/live/ammo_group_live/show.html.heex:96
#: lib/cannery_web/components/move_pack_component.ex:78
#: lib/cannery_web/live/pack_live/index.html.heex:144
#: lib/cannery_web/live/pack_live/show.html.heex:89
#, elixir-autogen, elixir-format
msgid "Move ammo"
msgstr "Mover munición"
@ -233,13 +233,13 @@ msgstr "Mover munición"
msgid "Set Unlimited"
msgstr "Activar ilimitados"
#: lib/cannery_web/live/ammo_group_live/show.html.heex:89
#: lib/cannery_web/live/pack_live/show.html.heex:85
#: lib/cannery_web/live/range_live/index.html.heex:38
#, elixir-autogen, elixir-format
msgid "Stage for range"
msgstr "Preparar para el campo de tiro"
#: lib/cannery_web/live/ammo_group_live/show.html.heex:88
#: lib/cannery_web/live/pack_live/show.html.heex:84
#: lib/cannery_web/live/range_live/index.html.heex:37
#, elixir-autogen, elixir-format
msgid "Unstage from range"
@ -289,7 +289,7 @@ msgstr ""
msgid "Delete invite for %{invite_name}"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.ex:161
#: lib/cannery_web/live/pack_live/show.ex:160
#: lib/cannery_web/live/range_live/index.html.heex:155
#, elixir-autogen, elixir-format
msgid "Delete shot record of %{shot_group_count} shots"
@ -313,18 +313,12 @@ msgstr ""
msgid "Edit %{tag_name}"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:164
#: lib/cannery_web/live/ammo_group_live/show.html.heex:62
#, elixir-autogen, elixir-format
msgid "Edit ammo group of %{ammo_group_count} bullets"
msgstr ""
#: lib/cannery_web/live/invite_live/index.html.heex:46
#, elixir-autogen, elixir-format
msgid "Edit invite for %{invite_name}"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.ex:146
#: lib/cannery_web/live/pack_live/show.ex:145
#, elixir-autogen, elixir-format
msgid "Edit shot group of %{shot_group_count} shots"
msgstr ""
@ -334,7 +328,7 @@ msgstr ""
msgid "Edit shot record of %{shot_group_count} shots"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:118
#: lib/cannery_web/live/pack_live/index.html.heex:120
#, elixir-autogen, elixir-format, fuzzy
msgid "Stage"
msgstr "Preparar munición"
@ -345,7 +339,7 @@ msgstr "Preparar munición"
msgid "Tag %{container_name}"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:117
#: lib/cannery_web/live/pack_live/index.html.heex:119
#, elixir-autogen, elixir-format
msgid "Unstage"
msgstr ""
@ -355,19 +349,25 @@ msgstr ""
msgid "View %{ammo_type_name}"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:176
#: lib/cannery_web/live/pack_live/index.html.heex:174
#, elixir-autogen, elixir-format, fuzzy
msgid "Clone ammo group of %{ammo_group_count} bullets"
msgid "Clone pack of %{pack_count} bullets"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:191
#: lib/cannery_web/live/ammo_group_live/show.html.heex:76
#: lib/cannery_web/live/pack_live/index.html.heex:189
#: lib/cannery_web/live/pack_live/show.html.heex:74
#, elixir-autogen, elixir-format, fuzzy
msgid "Delete ammo group of %{ammo_group_count} bullets"
msgid "Delete pack of %{pack_count} bullets"
msgstr ""
#: lib/cannery_web/live/pack_live/index.html.heex:164
#: lib/cannery_web/live/pack_live/show.html.heex:62
#, elixir-autogen, elixir-format, fuzzy
msgid "Edit pack of %{pack_count} bullets"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:152
#: lib/cannery_web/live/ammo_type_live/show.html.heex:206
#: lib/cannery_web/live/pack_live/index.html.heex:154
#, elixir-autogen, elixir-format, fuzzy
msgid "View ammo group of %{ammo_group_count} bullets"
msgid "View pack of %{pack_count} bullets"
msgstr ""

View File

@ -31,15 +31,15 @@ msgstr "Aministradores:"
#: lib/cannery_web/components/core_components/topbar.html.heex:58
#: lib/cannery_web/components/shot_group_table_component.ex:41
#: 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/pack_live/index.ex:75
#: lib/cannery_web/live/pack_live/index.ex:84
#: lib/cannery_web/live/pack_live/index.html.heex:3
#, elixir-autogen, elixir-format
msgid "Ammo"
msgstr "Munición"
#: lib/cannery_web/components/ammo_group_table_component.ex:96
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:22
#: lib/cannery_web/components/pack_table_component.ex:95
#: lib/cannery_web/live/pack_live/form_component.html.heex:22
#, elixir-autogen, elixir-format
msgid "Ammo type"
msgstr "Tipo de munición"
@ -90,9 +90,9 @@ msgstr "Cartucho"
msgid "Case material"
msgstr "Material del casquillo"
#: lib/cannery_web/components/ammo_group_table_component.ex:74
#: lib/cannery_web/components/move_ammo_group_component.ex:67
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:59
#: lib/cannery_web/components/move_pack_component.ex:65
#: lib/cannery_web/components/pack_table_component.ex:73
#: lib/cannery_web/live/pack_live/form_component.html.heex:59
#, elixir-autogen, elixir-format
msgid "Container"
msgstr "Contenedor"
@ -111,14 +111,14 @@ msgstr "Contenedores"
msgid "Corrosive"
msgstr "Corrosiva"
#: lib/cannery_web/components/ammo_group_table_component.ex:92
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:28
#: lib/cannery_web/components/pack_table_component.ex:91
#: lib/cannery_web/live/pack_live/form_component.html.heex:28
#, elixir-autogen, elixir-format
msgid "Count"
msgstr "Cantidad"
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:16
#: lib/cannery_web/live/ammo_group_live/show.html.heex:8
#: lib/cannery_web/components/core_components/pack_card.html.heex:16
#: lib/cannery_web/live/pack_live/show.html.heex:8
#, elixir-autogen, elixir-format
msgid "Count:"
msgstr "Cantidad:"
@ -196,7 +196,7 @@ msgid "Keep me logged in for 60 days"
msgstr "Mantener registrado durante 60 días"
#: lib/cannery_web/components/container_table_component.ex:47
#: lib/cannery_web/components/move_ammo_group_component.ex:69
#: lib/cannery_web/components/move_pack_component.ex:67
#: lib/cannery_web/live/container_live/form_component.html.heex:47
#, elixir-autogen, elixir-format
msgid "Location"
@ -262,7 +262,7 @@ msgstr "Nueva Invitación"
msgid "New Tag"
msgstr "Nueva Etiqueta"
#: lib/cannery_web/live/ammo_group_live/index.html.heex:92
#: lib/cannery_web/live/pack_live/index.html.heex:94
#, elixir-autogen, elixir-format
msgid "No Ammo"
msgstr "Sin Munición"
@ -292,15 +292,15 @@ msgstr "Sin etiquetas"
#: lib/cannery_web/components/add_shot_group_component.html.heex:38
#: lib/cannery_web/components/shot_group_table_component.ex:43
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:50
#: lib/cannery_web/live/ammo_group_live/show.ex:92
#: lib/cannery_web/live/pack_live/form_component.html.heex:50
#: lib/cannery_web/live/pack_live/show.ex:91
#: lib/cannery_web/live/range_live/form_component.html.heex:30
#, elixir-autogen, elixir-format
msgid "Notes"
msgstr "Notas"
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:29
#: lib/cannery_web/live/ammo_group_live/show.html.heex:24
#: lib/cannery_web/components/core_components/pack_card.html.heex:26
#: lib/cannery_web/live/pack_live/show.html.heex:24
#, elixir-autogen, elixir-format
msgid "Notes:"
msgstr "Notas:"
@ -316,13 +316,13 @@ msgstr "En la estantería"
msgid "Pressure"
msgstr "Presión"
#: lib/cannery_web/components/ammo_group_table_component.ex:82
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:35
#: lib/cannery_web/components/pack_table_component.ex:81
#: lib/cannery_web/live/pack_live/form_component.html.heex:35
#, elixir-autogen, elixir-format
msgid "Price paid"
msgstr "Precio pagado"
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:44
#: lib/cannery_web/components/core_components/pack_card.html.heex:41
#, elixir-autogen, elixir-format
msgid "Price paid:"
msgstr "Precio pagado:"
@ -366,7 +366,7 @@ msgstr "Simple:"
msgid "Steel"
msgstr "Acero"
#: lib/cannery_web/live/ammo_group_live/show.html.heex:113
#: lib/cannery_web/live/pack_live/show.html.heex:106
#, elixir-autogen, elixir-format
msgid "Stored in"
msgstr "Guardado en"
@ -402,16 +402,9 @@ msgstr "La página de seguimiento de armas autogestionada"
msgid "Tracer"
msgstr "Trazadora"
#: lib/cannery_web/components/ammo_type_table_component.ex:150
#: lib/cannery_web/components/container_table_component.ex:48
#: lib/cannery_web/components/move_ammo_group_component.ex:68
#: lib/cannery_web/live/ammo_group_live/index.html.heex:50
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:21
#: lib/cannery_web/live/ammo_type_live/index.html.heex:29
#: lib/cannery_web/live/ammo_type_live/show.html.heex:48
#: lib/cannery_web/components/move_pack_component.ex:66
#: lib/cannery_web/live/container_live/form_component.html.heex:39
#: lib/cannery_web/live/container_live/show.html.heex:97
#: lib/cannery_web/live/range_live/index.html.heex:86
#, elixir-autogen, elixir-format
msgid "Type"
msgstr "Tipo"
@ -442,8 +435,8 @@ msgstr "Tus datos se quedan contigo, sin excepciones"
msgid "No tags for this container"
msgstr "Contenedor sin etiquetas"
#: lib/cannery_web/components/ammo_group_table_component.ex:78
#: lib/cannery_web/components/core_components/topbar.html.heex:66
#: lib/cannery_web/components/pack_table_component.ex:77
#, elixir-autogen, elixir-format
msgid "Range"
msgstr "Campo de tiro"
@ -455,7 +448,7 @@ msgstr "Día de disparar"
#: lib/cannery_web/components/add_shot_group_component.html.heex:49
#: lib/cannery_web/components/shot_group_table_component.ex:44
#: lib/cannery_web/live/ammo_group_live/show.ex:93
#: lib/cannery_web/live/pack_live/show.ex:92
#: lib/cannery_web/live/range_live/form_component.html.heex:41
#, elixir-autogen, elixir-format
msgid "Date"
@ -472,12 +465,12 @@ msgid "No ammo staged"
msgstr "No hay munición preparada"
#: lib/cannery_web/components/add_shot_group_component.html.heex:3
#: lib/cannery_web/live/ammo_group_live/index.ex:30
#: lib/cannery_web/live/pack_live/index.ex:35
#, elixir-autogen, elixir-format
msgid "Record shots"
msgstr "Tiros récord"
#: lib/cannery_web/live/ammo_group_live/show.ex:42
#: lib/cannery_web/live/pack_live/show.ex:42
#: lib/cannery_web/live/range_live/index.ex:40
#, elixir-autogen, elixir-format
msgid "Edit Shot Records"
@ -501,7 +494,7 @@ msgid "Rounds left"
msgstr "Balas restantes"
#: lib/cannery_web/components/shot_group_table_component.ex:42
#: lib/cannery_web/live/ammo_group_live/show.ex:91
#: lib/cannery_web/live/pack_live/show.ex:90
#: lib/cannery_web/live/range_live/index.html.heex:69
#, elixir-autogen, elixir-format
msgid "Rounds shot"
@ -513,12 +506,12 @@ msgstr "Balas disparadas"
msgid "Shot Records"
msgstr "Récords de Tiro"
#: lib/cannery_web/live/ammo_group_live/index.ex:38
#: lib/cannery_web/live/pack_live/index.ex:43
#, elixir-autogen, elixir-format
msgid "Move ammo"
msgstr "Mover munición"
#: lib/cannery_web/components/move_ammo_group_component.ex:85
#: lib/cannery_web/components/move_pack_component.ex:83
#, elixir-autogen, elixir-format
msgid "No other containers"
msgstr "No hay otros contenedores"
@ -528,14 +521,14 @@ msgstr "No hay otros contenedores"
msgid "Shot log"
msgstr "Registro de tiros"
#: lib/cannery_web/components/ammo_group_table_component.ex:164
#: lib/cannery_web/components/ammo_group_table_component.ex:247
#: lib/cannery_web/components/ammo_type_table_component.ex:261
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:45
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:50
#: lib/cannery_web/live/ammo_group_live/show.html.heex:37
#: lib/cannery_web/live/ammo_group_live/show.html.heex:42
#: lib/cannery_web/components/core_components/pack_card.html.heex:42
#: lib/cannery_web/components/core_components/pack_card.html.heex:47
#: lib/cannery_web/components/pack_table_component.ex:163
#: lib/cannery_web/components/pack_table_component.ex:246
#: lib/cannery_web/live/ammo_type_live/show.html.heex:152
#: lib/cannery_web/live/pack_live/show.html.heex:37
#: lib/cannery_web/live/pack_live/show.html.heex:42
#, elixir-autogen, elixir-format
msgid "$%{amount}"
msgstr "$%{amount}"
@ -622,40 +615,40 @@ msgstr "Editar etiquetas de %{name}"
msgid "Rounds:"
msgstr "Balas:"
#: lib/cannery_web/components/ammo_group_table_component.ex:161
#: lib/cannery_web/components/ammo_group_table_component.ex:243
#: lib/cannery_web/components/ammo_type_table_component.ex:260
#: lib/cannery_web/components/pack_table_component.ex:160
#: lib/cannery_web/components/pack_table_component.ex:242
#: lib/cannery_web/live/ammo_type_live/show.html.heex:156
#, elixir-autogen, elixir-format
msgid "No cost information"
msgstr "No hay información de coste"
#: lib/cannery_web/components/ammo_group_table_component.ex:84
#: lib/cannery_web/components/pack_table_component.ex:83
#, elixir-autogen, elixir-format
msgid "% left"
msgstr "% restantes"
#: lib/cannery_web/live/ammo_group_live/show.html.heex:41
#: lib/cannery_web/live/pack_live/show.html.heex:41
#, elixir-autogen, elixir-format
msgid "Current value:"
msgstr "Valor actual:"
#: lib/cannery_web/live/ammo_group_live/show.html.heex:36
#: lib/cannery_web/live/pack_live/show.html.heex:36
#, elixir-autogen, elixir-format
msgid "Original cost:"
msgstr "Coste original:"
#: lib/cannery_web/live/ammo_group_live/show.html.heex:13
#: lib/cannery_web/live/pack_live/show.html.heex:13
#, elixir-autogen, elixir-format
msgid "Original count:"
msgstr "Cantidad original:"
#: lib/cannery_web/live/ammo_group_live/show.html.heex:18
#: lib/cannery_web/live/pack_live/show.html.heex:18
#, elixir-autogen, elixir-format
msgid "Percentage left:"
msgstr "Pocentaje restante:"
#: lib/cannery_web/live/ammo_group_live/show.html.heex:126
#: lib/cannery_web/live/pack_live/show.html.heex:119
#, elixir-autogen, elixir-format
msgid "Rounds used"
msgstr "Balas usadas"
@ -685,13 +678,13 @@ msgstr "Registrarse"
msgid "Reset your password"
msgstr "Reestablecer contraseña"
#: lib/cannery_web/live/ammo_group_live/show.ex:41
#: lib/cannery_web/live/pack_live/show.ex:41
#: lib/cannery_web/live/range_live/index.ex:32
#, elixir-autogen, elixir-format
msgid "Record Shots"
msgstr "Tiros Récord"
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:69
#: lib/cannery_web/live/pack_live/form_component.html.heex:69
#, elixir-autogen, elixir-format
msgid "Copies"
msgstr "Copias"
@ -750,12 +743,12 @@ msgstr "Ver código fuente"
msgid "Catalog"
msgstr "Catálogo"
#: lib/cannery_web/live/ammo_group_live/show.ex:45
#: lib/cannery_web/live/pack_live/show.ex:45
#, elixir-autogen, elixir-format
msgid "Edit Ammo"
msgstr "Editar Munición"
#: lib/cannery_web/live/ammo_group_live/show.ex:43
#: lib/cannery_web/live/pack_live/show.ex:43
#, elixir-autogen, elixir-format
msgid "Move Ammo"
msgstr "Mover Munición"
@ -765,12 +758,12 @@ msgstr "Mover Munición"
msgid "No ammo in this container"
msgstr "No hay munición en este contenedor"
#: lib/cannery_web/live/ammo_group_live/show.ex:44
#: lib/cannery_web/live/pack_live/show.ex:44
#, elixir-autogen, elixir-format
msgid "Show Ammo"
msgstr "Mostrar Munición"
#: lib/cannery_web/live/ammo_group_live/show.html.heex:118
#: lib/cannery_web/live/pack_live/show.html.heex:111
#, elixir-autogen, elixir-format
msgid "This ammo is not in a container"
msgstr "Esta munición no está en un contenedor"
@ -799,25 +792,25 @@ msgid "Leave \"Uses left\" blank to make invite unlimited"
msgstr ""
"Deje \"Usos restantes\" en blanco para hacer las invitaciónes ilimitadas"
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:54
#: lib/cannery_web/components/core_components/pack_card.html.heex:51
#, elixir-autogen, elixir-format
msgid "Container:"
msgstr "Contenedor:"
#: lib/cannery_web/live/ammo_group_live/index.html.heex:85
#: lib/cannery_web/live/ammo_type_live/index.html.heex:64
#: lib/cannery_web/live/ammo_type_live/show.html.heex:166
#: lib/cannery_web/live/pack_live/index.html.heex:87
#, elixir-autogen, elixir-format
msgid "Show used"
msgstr "Mostrar usadas"
#: lib/cannery_web/components/ammo_group_table_component.ex:202
#: lib/cannery_web/live/ammo_group_live/show.html.heex:19
#: lib/cannery_web/components/pack_table_component.ex:201
#: lib/cannery_web/live/pack_live/show.html.heex:19
#, elixir-autogen, elixir-format
msgid "%{percentage}%"
msgstr "%{percentage}%"
#: lib/cannery_web/live/range_live/index.ex:153
#: lib/cannery_web/live/range_live/index.ex:154
#, elixir-autogen, elixir-format, fuzzy
msgid "Rounds shot: %{count}"
msgstr "Balas disparadas: %{count}"
@ -998,28 +991,28 @@ msgstr ""
msgid "Edit %{ammo_type_name}"
msgstr "Editar %{ammo_type_name}"
#: lib/cannery_web/components/ammo_group_table_component.ex:251
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:17
#: lib/cannery_web/components/core_components/pack_card.html.heex:17
#: lib/cannery_web/components/pack_table_component.ex:250
#, elixir-autogen, elixir-format
msgid "Empty"
msgstr "Vacio"
#: lib/cannery_web/components/ammo_group_table_component.ex:81
#: lib/cannery_web/components/pack_table_component.ex:80
#, elixir-autogen, elixir-format
msgid "CPR"
msgstr ""
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:49
#: lib/cannery_web/components/core_components/pack_card.html.heex:46
#, elixir-autogen, elixir-format
msgid "CPR:"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:88
#: lib/cannery_web/components/pack_table_component.ex:87
#, elixir-autogen, elixir-format
msgid "Original Count"
msgstr "Cantidad Original"
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:24
#: lib/cannery_web/components/core_components/pack_card.html.heex:21
#, elixir-autogen, elixir-format
msgid "Original Count:"
msgstr "Cantidad Original:"
@ -1029,34 +1022,34 @@ msgstr "Cantidad Original:"
msgid "Home"
msgstr "Menu principal"
#: lib/cannery_web/components/ammo_group_table_component.ex:64
#: lib/cannery_web/components/pack_table_component.ex:63
#, elixir-autogen, elixir-format
msgid "Last used on"
msgstr "Usada por última vez en"
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:39
#: lib/cannery_web/components/core_components/pack_card.html.heex:36
#, elixir-autogen, elixir-format
msgid "Last used on:"
msgstr "Usada por última vez en:"
#: lib/cannery_web/components/ammo_group_table_component.ex:182
#: lib/cannery_web/components/pack_table_component.ex:181
#, elixir-autogen, elixir-format
msgid "Never used"
msgstr "Nunca usada"
#: lib/cannery_web/components/ammo_group_table_component.ex:69
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:42
#: lib/cannery_web/components/pack_table_component.ex:68
#: lib/cannery_web/live/pack_live/form_component.html.heex:42
#, elixir-autogen, elixir-format
msgid "Purchased on"
msgstr "Comprada en"
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:34
#: lib/cannery_web/live/ammo_group_live/show.html.heex:30
#: lib/cannery_web/components/core_components/pack_card.html.heex:31
#: lib/cannery_web/live/pack_live/show.html.heex:30
#, elixir-autogen, elixir-format
msgid "Purchased on:"
msgstr "Comprada en:"
#: lib/cannery_web/live/ammo_group_live/index.ex:46
#: lib/cannery_web/live/pack_live/index.ex:51
#, elixir-autogen, elixir-format, fuzzy
msgid "Edit ammo"
msgstr "Editar munición"
@ -1072,7 +1065,7 @@ msgstr "Sin tipo de Munición"
msgid "Search catalog"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:79
#: lib/cannery_web/live/pack_live/index.html.heex:81
#, elixir-autogen, elixir-format, fuzzy
msgid "Search ammo"
msgstr ""
@ -1227,12 +1220,12 @@ msgstr ""
msgid "Really great weather"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:60
#: lib/cannery_web/components/ammo_type_table_component.ex:100
#: lib/cannery_web/components/container_table_component.ex:67
#: lib/cannery_web/components/move_ammo_group_component.ex:70
#: lib/cannery_web/components/move_pack_component.ex:68
#: lib/cannery_web/components/pack_table_component.ex:59
#: lib/cannery_web/components/shot_group_table_component.ex:45
#: lib/cannery_web/live/ammo_group_live/show.ex:94
#: lib/cannery_web/live/pack_live/show.ex:93
#, elixir-autogen, elixir-format
msgid "Actions"
msgstr ""
@ -1247,7 +1240,7 @@ msgstr ""
msgid "Log out"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:92
#: lib/cannery_web/components/pack_table_component.ex:91
#, elixir-autogen, elixir-format
msgid "Current Count"
msgstr ""
@ -1258,9 +1251,9 @@ msgstr ""
msgid "Close modal"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:56
#: lib/cannery_web/live/ammo_type_live/index.html.heex:35
#: lib/cannery_web/live/container_live/show.html.heex:103
#: lib/cannery_web/live/pack_live/index.html.heex:58
#: lib/cannery_web/live/range_live/index.html.heex:92
#, elixir-autogen, elixir-format
msgid "All"
@ -1332,7 +1325,7 @@ msgstr ""
msgid "Load grains:"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:29
#: lib/cannery_web/live/pack_live/index.html.heex:29
#, elixir-autogen, elixir-format, fuzzy
msgid "No ammo"
msgstr "Sin Munición"
@ -1342,11 +1335,11 @@ msgstr "Sin Munición"
msgid "None specified"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:59
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:25
#: lib/cannery_web/live/ammo_type_live/index.html.heex:38
#: lib/cannery_web/live/ammo_type_live/show.html.heex:58
#: lib/cannery_web/live/container_live/show.html.heex:106
#: lib/cannery_web/live/pack_live/index.html.heex:61
#: lib/cannery_web/live/range_live/index.html.heex:95
#, elixir-autogen, elixir-format
msgid "Pistol"
@ -1367,11 +1360,11 @@ msgstr "Tipo de espoleta"
msgid "Projectile"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:57
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:25
#: lib/cannery_web/live/ammo_type_live/index.html.heex:36
#: lib/cannery_web/live/ammo_type_live/show.html.heex:56
#: lib/cannery_web/live/container_live/show.html.heex:104
#: lib/cannery_web/live/pack_live/index.html.heex:59
#: lib/cannery_web/live/range_live/index.html.heex:93
#, elixir-autogen, elixir-format
msgid "Rifle"
@ -1421,11 +1414,11 @@ msgstr ""
msgid "Shot type:"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:58
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:25
#: lib/cannery_web/live/ammo_type_live/index.html.heex:37
#: lib/cannery_web/live/ammo_type_live/show.html.heex:54
#: lib/cannery_web/live/container_live/show.html.heex:105
#: lib/cannery_web/live/pack_live/index.html.heex:60
#: lib/cannery_web/live/range_live/index.html.heex:94
#, elixir-autogen, elixir-format
msgid "Shotgun"
@ -1463,3 +1456,14 @@ msgstr ""
#, elixir-autogen, elixir-format
msgid "Wadding:"
msgstr ""
#: lib/cannery_web/components/ammo_type_table_component.ex:150
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:21
#: lib/cannery_web/live/ammo_type_live/index.html.heex:29
#: lib/cannery_web/live/ammo_type_live/show.html.heex:48
#: lib/cannery_web/live/container_live/show.html.heex:97
#: lib/cannery_web/live/pack_live/index.html.heex:50
#: lib/cannery_web/live/range_live/index.html.heex:86
#, elixir-autogen, elixir-format
msgid "Class"
msgstr ""

View File

@ -161,22 +161,22 @@ msgstr "Debe confirmar su cuenta e iniciar sesión para acceder a esta página."
msgid "Tag could not be removed"
msgstr "La etiqueta no pudo ser eliminada"
#: lib/cannery_web/live/ammo_group_live/form_component.ex:160
#: lib/cannery_web/live/pack_live/form_component.ex:159
#, elixir-autogen, elixir-format
msgid "Could not parse number of copies"
msgstr "No se ha podido procesar el número de copias"
#: lib/cannery_web/live/ammo_group_live/form_component.ex:150
#: lib/cannery_web/live/pack_live/form_component.ex:149
#, elixir-autogen, elixir-format
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:1114
#: lib/cannery/ammo.ex:1123
#, elixir-autogen, elixir-format
msgid "Invalid multiplier"
msgstr "Multiplicador inválido"
#: lib/cannery/ammo/ammo_group.ex:92
#: lib/cannery/ammo/pack.ex:92
#, elixir-autogen, elixir-format
msgid "Please select an ammo type and container"
msgstr "Por favor escoja un tipo de munición y un contenedor"
@ -201,7 +201,7 @@ msgstr ""
msgid "Ammo left must be at least 0"
msgstr ""
#: lib/cannery/activity_log/shot_group.ex:122
#: lib/cannery/activity_log/shot_group.ex:119
#, elixir-autogen, elixir-format, fuzzy
msgid "Count can be at most %{count} shots"
msgstr "El recuento debe ser menos de %{count}"

View File

@ -73,8 +73,8 @@ msgstr "Está seguro que desea eliminar %{email}? Esta acción es permanente!"
msgid "Are you sure you want to delete %{name}?"
msgstr "Está seguro que desea eliminar %{name}?"
#: lib/cannery_web/live/ammo_group_live/index.html.heex:189
#: lib/cannery_web/live/ammo_group_live/show.html.heex:74
#: lib/cannery_web/live/pack_live/index.html.heex:187
#: lib/cannery_web/live/pack_live/show.html.heex:72
#, elixir-autogen, elixir-format
msgid "Are you sure you want to delete this ammo?"
msgstr "Está seguro que desea eliminar esta munición?"
@ -129,10 +129,10 @@ msgid "Please check your email to verify your account"
msgstr "Por favor chequea el correo para verificar tu cuenta"
#: lib/cannery_web/components/add_shot_group_component.html.heex:59
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:85
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:351
#: lib/cannery_web/live/container_live/form_component.html.heex:59
#: lib/cannery_web/live/invite_live/form_component.html.heex:37
#: lib/cannery_web/live/pack_live/form_component.html.heex:85
#: lib/cannery_web/live/range_live/form_component.html.heex:47
#: lib/cannery_web/live/tag_live/form_component.html.heex:39
#, elixir-autogen, elixir-format
@ -175,13 +175,13 @@ msgstr "Tiros registrados exitosamente"
msgid "Are you sure you want to unstage this ammo?"
msgstr "Está seguro que desea desmontar esta munición?"
#: lib/cannery_web/live/ammo_group_live/show.ex:159
#: lib/cannery_web/live/pack_live/show.ex:158
#: lib/cannery_web/live/range_live/index.html.heex:152
#, elixir-autogen, elixir-format
msgid "Are you sure you want to delete this shot record?"
msgstr "¿Está segure que quiere borrar este récord de disparos?"
#: lib/cannery_web/live/ammo_group_live/show.ex:81
#: lib/cannery_web/live/pack_live/show.ex:80
#: lib/cannery_web/live/range_live/index.ex:79
#, elixir-autogen, elixir-format
msgid "Shot records deleted succesfully"
@ -197,7 +197,7 @@ msgstr "Récord de disparos actualizado exitosamente"
msgid "%{email} confirmed successfully."
msgstr "%{email} confirmado exitosamente."
#: lib/cannery_web/components/move_ammo_group_component.ex:54
#: lib/cannery_web/components/move_pack_component.ex:52
#, elixir-autogen, elixir-format
msgid "Ammo moved to %{name} successfully"
msgstr "Munición movida a %{name} exitosamente"
@ -212,13 +212,13 @@ msgstr "Copiado al portapapeles"
msgid "%{name} removed successfully"
msgstr "%{name} eliminado exitosamente"
#: lib/cannery_web/live/ammo_group_live/index.html.heex:10
#: lib/cannery_web/live/ammo_group_live/index.html.heex:20
#: lib/cannery_web/live/pack_live/index.html.heex:10
#: lib/cannery_web/live/pack_live/index.html.heex:20
#, elixir-autogen, elixir-format
msgid "You'll need to"
msgstr "Necesitará hacerlo"
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:78
#: lib/cannery_web/live/pack_live/form_component.html.heex:78
#, elixir-autogen, elixir-format
msgid "Creating..."
msgstr "Creando..."
@ -233,23 +233,23 @@ msgstr "¿Está segure de que quiere cambiar el idioma?"
msgid "Language updated successfully."
msgstr "Idioma cambiado exitosamente."
#: lib/cannery_web/live/ammo_group_live/index.ex:89
#: lib/cannery_web/live/ammo_group_live/show.ex:55
#: lib/cannery_web/live/pack_live/index.ex:94
#: lib/cannery_web/live/pack_live/show.ex:55
#, elixir-autogen, elixir-format
msgid "Ammo deleted succesfully"
msgstr "Munición borrada exitosamente"
#: lib/cannery_web/live/range_live/index.ex:93
#: lib/cannery_web/live/range_live/index.ex:92
#, elixir-autogen, elixir-format, fuzzy
msgid "Ammo unstaged succesfully"
msgstr "Munición descargada exitosamente"
#: lib/cannery_web/live/ammo_group_live/form_component.ex:126
#: lib/cannery_web/live/pack_live/form_component.ex:125
#, elixir-autogen, elixir-format
msgid "Ammo updated successfully"
msgstr "Munición actualizada exitosamente"
#: lib/cannery_web/live/ammo_group_live/form_component.ex:185
#: lib/cannery_web/live/pack_live/form_component.ex:184
#, elixir-autogen, elixir-format
msgid "Ammo added successfully"
msgid_plural "Ammo added successfully"

View File

@ -23,14 +23,14 @@ 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:54
#: lib/cannery_web/live/ammo_group_live/index.ex:62
#: lib/cannery_web/live/ammo_group_live/index.html.heex:38
#: lib/cannery_web/live/pack_live/index.ex:59
#: lib/cannery_web/live/pack_live/index.ex:67
#: lib/cannery_web/live/pack_live/index.html.heex:38
#, elixir-autogen, elixir-format
msgid "Add Ammo"
msgstr "ajouter munition"
#: lib/cannery_web/live/ammo_group_live/index.html.heex:34
#: lib/cannery_web/live/pack_live/index.html.heex:34
#, elixir-autogen, elixir-format
msgid "Add your first box!"
msgstr "Ajoutez votre première caisse !"
@ -134,10 +134,10 @@ msgid "Reset password"
msgstr "Réinitialisé le mot de passe"
#: lib/cannery_web/components/add_shot_group_component.html.heex:57
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:84
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:350
#: lib/cannery_web/live/container_live/form_component.html.heex:57
#: lib/cannery_web/live/invite_live/form_component.html.heex:35
#: lib/cannery_web/live/pack_live/form_component.html.heex:84
#: lib/cannery_web/live/range_live/form_component.html.heex:45
#: lib/cannery_web/live/tag_live/form_component.html.heex:37
#, elixir-autogen, elixir-format
@ -169,19 +169,19 @@ 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:125
#: lib/cannery_web/live/ammo_group_live/show.html.heex:103
#: lib/cannery_web/live/pack_live/index.html.heex:127
#: lib/cannery_web/live/pack_live/show.html.heex:96
#: lib/cannery_web/live/range_live/index.html.heex:45
#, elixir-autogen, elixir-format
msgid "Record shots"
msgstr "Enregistrer des tirs"
#: lib/cannery_web/components/move_ammo_group_component.ex:90
#: lib/cannery_web/components/move_pack_component.ex:88
#, elixir-autogen, elixir-format
msgid "Add another container!"
msgstr "Ajoutez un autre conteneur!"
#: lib/cannery_web/components/move_ammo_group_component.ex:126
#: lib/cannery_web/components/move_pack_component.ex:124
#, elixir-autogen, elixir-format
msgid "Select"
msgstr "Sélectionner"
@ -191,12 +191,12 @@ msgstr "Sélectionner"
msgid "Copy to clipboard"
msgstr "Copier dans le presse-papier"
#: lib/cannery_web/live/ammo_group_live/index.html.heex:14
#: lib/cannery_web/live/pack_live/index.html.heex:14
#, elixir-autogen, elixir-format
msgid "add a container first"
msgstr "ajouter un conteneur en premier"
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:77
#: lib/cannery_web/live/pack_live/form_component.html.heex:77
#, elixir-autogen, elixir-format
msgid "Create"
msgstr "Créer"
@ -211,19 +211,19 @@ msgstr "Changer la langue"
msgid "Change language"
msgstr "Changer la langue"
#: lib/cannery_web/live/ammo_group_live/show.html.heex:55
#: lib/cannery_web/live/pack_live/show.html.heex:55
#, elixir-autogen, elixir-format
msgid "View in Catalog"
msgstr "Voir en catalogue"
#: lib/cannery_web/live/ammo_group_live/index.html.heex:24
#: lib/cannery_web/live/pack_live/index.html.heex:24
#, elixir-autogen, elixir-format
msgid "add an ammo type first"
msgstr "Ajoutez d'abord un type de munitions"
#: lib/cannery_web/components/move_ammo_group_component.ex:80
#: lib/cannery_web/live/ammo_group_live/index.html.heex:142
#: lib/cannery_web/live/ammo_group_live/show.html.heex:96
#: lib/cannery_web/components/move_pack_component.ex:78
#: lib/cannery_web/live/pack_live/index.html.heex:144
#: lib/cannery_web/live/pack_live/show.html.heex:89
#, elixir-autogen, elixir-format
msgid "Move ammo"
msgstr ""
@ -233,13 +233,13 @@ msgstr ""
msgid "Set Unlimited"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.html.heex:89
#: lib/cannery_web/live/pack_live/show.html.heex:85
#: lib/cannery_web/live/range_live/index.html.heex:38
#, elixir-autogen, elixir-format
msgid "Stage for range"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.html.heex:88
#: lib/cannery_web/live/pack_live/show.html.heex:84
#: lib/cannery_web/live/range_live/index.html.heex:37
#, elixir-autogen, elixir-format
msgid "Unstage from range"
@ -289,7 +289,7 @@ msgstr ""
msgid "Delete invite for %{invite_name}"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.ex:161
#: lib/cannery_web/live/pack_live/show.ex:160
#: lib/cannery_web/live/range_live/index.html.heex:155
#, elixir-autogen, elixir-format
msgid "Delete shot record of %{shot_group_count} shots"
@ -313,18 +313,12 @@ msgstr ""
msgid "Edit %{tag_name}"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:164
#: lib/cannery_web/live/ammo_group_live/show.html.heex:62
#, elixir-autogen, elixir-format
msgid "Edit ammo group of %{ammo_group_count} bullets"
msgstr ""
#: lib/cannery_web/live/invite_live/index.html.heex:46
#, elixir-autogen, elixir-format
msgid "Edit invite for %{invite_name}"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.ex:146
#: lib/cannery_web/live/pack_live/show.ex:145
#, elixir-autogen, elixir-format
msgid "Edit shot group of %{shot_group_count} shots"
msgstr ""
@ -334,7 +328,7 @@ msgstr ""
msgid "Edit shot record of %{shot_group_count} shots"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:118
#: lib/cannery_web/live/pack_live/index.html.heex:120
#, elixir-autogen, elixir-format, fuzzy
msgid "Stage"
msgstr "Munition préparée"
@ -345,7 +339,7 @@ msgstr "Munition préparée"
msgid "Tag %{container_name}"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:117
#: lib/cannery_web/live/pack_live/index.html.heex:119
#, elixir-autogen, elixir-format
msgid "Unstage"
msgstr ""
@ -355,19 +349,25 @@ msgstr ""
msgid "View %{ammo_type_name}"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:176
#: lib/cannery_web/live/pack_live/index.html.heex:174
#, elixir-autogen, elixir-format, fuzzy
msgid "Clone ammo group of %{ammo_group_count} bullets"
msgid "Clone pack of %{pack_count} bullets"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:191
#: lib/cannery_web/live/ammo_group_live/show.html.heex:76
#: lib/cannery_web/live/pack_live/index.html.heex:189
#: lib/cannery_web/live/pack_live/show.html.heex:74
#, elixir-autogen, elixir-format, fuzzy
msgid "Delete ammo group of %{ammo_group_count} bullets"
msgid "Delete pack of %{pack_count} bullets"
msgstr ""
#: lib/cannery_web/live/pack_live/index.html.heex:164
#: lib/cannery_web/live/pack_live/show.html.heex:62
#, elixir-autogen, elixir-format, fuzzy
msgid "Edit pack of %{pack_count} bullets"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:152
#: lib/cannery_web/live/ammo_type_live/show.html.heex:206
#: lib/cannery_web/live/pack_live/index.html.heex:154
#, elixir-autogen, elixir-format, fuzzy
msgid "View ammo group of %{ammo_group_count} bullets"
msgid "View pack of %{pack_count} bullets"
msgstr ""

View File

@ -31,15 +31,15 @@ msgstr "Administrateur·ices:"
#: lib/cannery_web/components/core_components/topbar.html.heex:58
#: lib/cannery_web/components/shot_group_table_component.ex:41
#: 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/pack_live/index.ex:75
#: lib/cannery_web/live/pack_live/index.ex:84
#: lib/cannery_web/live/pack_live/index.html.heex:3
#, elixir-autogen, elixir-format
msgid "Ammo"
msgstr "Munition"
#: lib/cannery_web/components/ammo_group_table_component.ex:96
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:22
#: lib/cannery_web/components/pack_table_component.ex:95
#: lib/cannery_web/live/pack_live/form_component.html.heex:22
#, elixir-autogen, elixir-format
msgid "Ammo type"
msgstr "Type de munition"
@ -90,9 +90,9 @@ msgstr "Cartouche"
msgid "Case material"
msgstr "Matériau de la caisse"
#: lib/cannery_web/components/ammo_group_table_component.ex:74
#: lib/cannery_web/components/move_ammo_group_component.ex:67
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:59
#: lib/cannery_web/components/move_pack_component.ex:65
#: lib/cannery_web/components/pack_table_component.ex:73
#: lib/cannery_web/live/pack_live/form_component.html.heex:59
#, elixir-autogen, elixir-format
msgid "Container"
msgstr "Conteneur"
@ -111,14 +111,14 @@ msgstr "Conteneurs"
msgid "Corrosive"
msgstr "Corrosive"
#: lib/cannery_web/components/ammo_group_table_component.ex:92
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:28
#: lib/cannery_web/components/pack_table_component.ex:91
#: lib/cannery_web/live/pack_live/form_component.html.heex:28
#, elixir-autogen, elixir-format
msgid "Count"
msgstr "Quantité"
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:16
#: lib/cannery_web/live/ammo_group_live/show.html.heex:8
#: lib/cannery_web/components/core_components/pack_card.html.heex:16
#: lib/cannery_web/live/pack_live/show.html.heex:8
#, elixir-autogen, elixir-format
msgid "Count:"
msgstr "Quantité:"
@ -196,7 +196,7 @@ msgid "Keep me logged in for 60 days"
msgstr "Me garder authentifié durant 60 jours"
#: lib/cannery_web/components/container_table_component.ex:47
#: lib/cannery_web/components/move_ammo_group_component.ex:69
#: lib/cannery_web/components/move_pack_component.ex:67
#: lib/cannery_web/live/container_live/form_component.html.heex:47
#, elixir-autogen, elixir-format
msgid "Location"
@ -262,7 +262,7 @@ msgstr "Nouvelle invitation"
msgid "New Tag"
msgstr "Nouveau tag"
#: lib/cannery_web/live/ammo_group_live/index.html.heex:92
#: lib/cannery_web/live/pack_live/index.html.heex:94
#, elixir-autogen, elixir-format
msgid "No Ammo"
msgstr "Aucune munition"
@ -292,15 +292,15 @@ msgstr "Aucun tag"
#: lib/cannery_web/components/add_shot_group_component.html.heex:38
#: lib/cannery_web/components/shot_group_table_component.ex:43
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:50
#: lib/cannery_web/live/ammo_group_live/show.ex:92
#: lib/cannery_web/live/pack_live/form_component.html.heex:50
#: lib/cannery_web/live/pack_live/show.ex:91
#: lib/cannery_web/live/range_live/form_component.html.heex:30
#, elixir-autogen, elixir-format
msgid "Notes"
msgstr "Notes"
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:29
#: lib/cannery_web/live/ammo_group_live/show.html.heex:24
#: lib/cannery_web/components/core_components/pack_card.html.heex:26
#: lib/cannery_web/live/pack_live/show.html.heex:24
#, elixir-autogen, elixir-format
msgid "Notes:"
msgstr "Notes:"
@ -316,13 +316,13 @@ msgstr "Sur létagère"
msgid "Pressure"
msgstr "Pression"
#: lib/cannery_web/components/ammo_group_table_component.ex:82
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:35
#: lib/cannery_web/components/pack_table_component.ex:81
#: lib/cannery_web/live/pack_live/form_component.html.heex:35
#, elixir-autogen, elixir-format
msgid "Price paid"
msgstr "Prix payé"
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:44
#: lib/cannery_web/components/core_components/pack_card.html.heex:41
#, elixir-autogen, elixir-format
msgid "Price paid:"
msgstr "Prix payé:"
@ -366,7 +366,7 @@ msgstr "Simple:"
msgid "Steel"
msgstr "Acier"
#: lib/cannery_web/live/ammo_group_live/show.html.heex:113
#: lib/cannery_web/live/pack_live/show.html.heex:106
#, elixir-autogen, elixir-format
msgid "Stored in"
msgstr "Est stocké dans"
@ -403,16 +403,9 @@ msgstr "Le site web de suivi darme à feux auto-hébergé"
msgid "Tracer"
msgstr "Traceuse"
#: lib/cannery_web/components/ammo_type_table_component.ex:150
#: lib/cannery_web/components/container_table_component.ex:48
#: lib/cannery_web/components/move_ammo_group_component.ex:68
#: lib/cannery_web/live/ammo_group_live/index.html.heex:50
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:21
#: lib/cannery_web/live/ammo_type_live/index.html.heex:29
#: lib/cannery_web/live/ammo_type_live/show.html.heex:48
#: lib/cannery_web/components/move_pack_component.ex:66
#: lib/cannery_web/live/container_live/form_component.html.heex:39
#: lib/cannery_web/live/container_live/show.html.heex:97
#: lib/cannery_web/live/range_live/index.html.heex:86
#, elixir-autogen, elixir-format
msgid "Type"
msgstr "Type"
@ -443,8 +436,8 @@ msgstr "Vos données restent avec vous, point final"
msgid "No tags for this container"
msgstr "Aucun tag pour ce conteneur"
#: lib/cannery_web/components/ammo_group_table_component.ex:78
#: lib/cannery_web/components/core_components/topbar.html.heex:66
#: lib/cannery_web/components/pack_table_component.ex:77
#, elixir-autogen, elixir-format
msgid "Range"
msgstr "Portée"
@ -456,7 +449,7 @@ msgstr "Journée de stand"
#: lib/cannery_web/components/add_shot_group_component.html.heex:49
#: lib/cannery_web/components/shot_group_table_component.ex:44
#: lib/cannery_web/live/ammo_group_live/show.ex:93
#: lib/cannery_web/live/pack_live/show.ex:92
#: lib/cannery_web/live/range_live/form_component.html.heex:41
#, elixir-autogen, elixir-format
msgid "Date"
@ -473,12 +466,12 @@ 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:30
#: lib/cannery_web/live/pack_live/index.ex:35
#, elixir-autogen, elixir-format
msgid "Record shots"
msgstr "Tirs enregistrés"
#: lib/cannery_web/live/ammo_group_live/show.ex:42
#: lib/cannery_web/live/pack_live/show.ex:42
#: lib/cannery_web/live/range_live/index.ex:40
#, elixir-autogen, elixir-format
msgid "Edit Shot Records"
@ -502,7 +495,7 @@ msgid "Rounds left"
msgstr "Cartouches restantes"
#: lib/cannery_web/components/shot_group_table_component.ex:42
#: lib/cannery_web/live/ammo_group_live/show.ex:91
#: lib/cannery_web/live/pack_live/show.ex:90
#: lib/cannery_web/live/range_live/index.html.heex:69
#, elixir-autogen, elixir-format
msgid "Rounds shot"
@ -514,12 +507,12 @@ msgstr "Cartouches tirées"
msgid "Shot Records"
msgstr "Enregistrements de tir"
#: lib/cannery_web/live/ammo_group_live/index.ex:38
#: lib/cannery_web/live/pack_live/index.ex:43
#, elixir-autogen, elixir-format
msgid "Move ammo"
msgstr "Déplacer munition"
#: lib/cannery_web/components/move_ammo_group_component.ex:85
#: lib/cannery_web/components/move_pack_component.ex:83
#, elixir-autogen, elixir-format
msgid "No other containers"
msgstr "Aucun autre conteneur"
@ -529,14 +522,14 @@ msgstr "Aucun autre conteneur"
msgid "Shot log"
msgstr "Évènements de tir"
#: lib/cannery_web/components/ammo_group_table_component.ex:164
#: lib/cannery_web/components/ammo_group_table_component.ex:247
#: lib/cannery_web/components/ammo_type_table_component.ex:261
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:45
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:50
#: lib/cannery_web/live/ammo_group_live/show.html.heex:37
#: lib/cannery_web/live/ammo_group_live/show.html.heex:42
#: lib/cannery_web/components/core_components/pack_card.html.heex:42
#: lib/cannery_web/components/core_components/pack_card.html.heex:47
#: lib/cannery_web/components/pack_table_component.ex:163
#: lib/cannery_web/components/pack_table_component.ex:246
#: lib/cannery_web/live/ammo_type_live/show.html.heex:152
#: lib/cannery_web/live/pack_live/show.html.heex:37
#: lib/cannery_web/live/pack_live/show.html.heex:42
#, elixir-autogen, elixir-format
msgid "$%{amount}"
msgstr "%{amount}$"
@ -623,40 +616,40 @@ msgstr "Éditer les tags de %{name}"
msgid "Rounds:"
msgstr "Cartouches:"
#: lib/cannery_web/components/ammo_group_table_component.ex:161
#: lib/cannery_web/components/ammo_group_table_component.ex:243
#: lib/cannery_web/components/ammo_type_table_component.ex:260
#: lib/cannery_web/components/pack_table_component.ex:160
#: lib/cannery_web/components/pack_table_component.ex:242
#: lib/cannery_web/live/ammo_type_live/show.html.heex:156
#, elixir-autogen, elixir-format
msgid "No cost information"
msgstr "Aucune information de prix"
#: lib/cannery_web/components/ammo_group_table_component.ex:84
#: lib/cannery_web/components/pack_table_component.ex:83
#, elixir-autogen, elixir-format
msgid "% left"
msgstr "%restante"
#: lib/cannery_web/live/ammo_group_live/show.html.heex:41
#: lib/cannery_web/live/pack_live/show.html.heex:41
#, elixir-autogen, elixir-format
msgid "Current value:"
msgstr "Valeur actuelle:"
#: lib/cannery_web/live/ammo_group_live/show.html.heex:36
#: lib/cannery_web/live/pack_live/show.html.heex:36
#, elixir-autogen, elixir-format
msgid "Original cost:"
msgstr "Coût original:"
#: lib/cannery_web/live/ammo_group_live/show.html.heex:13
#: lib/cannery_web/live/pack_live/show.html.heex:13
#, elixir-autogen, elixir-format
msgid "Original count:"
msgstr "Nombre original:"
#: lib/cannery_web/live/ammo_group_live/show.html.heex:18
#: lib/cannery_web/live/pack_live/show.html.heex:18
#, elixir-autogen, elixir-format
msgid "Percentage left:"
msgstr "Pourcentage restant:"
#: lib/cannery_web/live/ammo_group_live/show.html.heex:126
#: lib/cannery_web/live/pack_live/show.html.heex:119
#, elixir-autogen, elixir-format
msgid "Rounds used"
msgstr "Cartouches utilisées"
@ -686,13 +679,13 @@ msgstr "Senregistrer"
msgid "Reset your password"
msgstr "Réinitialiser votre mot de passe"
#: lib/cannery_web/live/ammo_group_live/show.ex:41
#: lib/cannery_web/live/pack_live/show.ex:41
#: lib/cannery_web/live/range_live/index.ex:32
#, elixir-autogen, elixir-format
msgid "Record Shots"
msgstr "Enregistrer des tirs"
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:69
#: lib/cannery_web/live/pack_live/form_component.html.heex:69
#, elixir-autogen, elixir-format
msgid "Copies"
msgstr "Exemplaires"
@ -751,12 +744,12 @@ msgstr "Voir le code source"
msgid "Catalog"
msgstr "Catalogue"
#: lib/cannery_web/live/ammo_group_live/show.ex:45
#: lib/cannery_web/live/pack_live/show.ex:45
#, elixir-autogen, elixir-format, fuzzy
msgid "Edit Ammo"
msgstr "Éditer le type de munition"
#: lib/cannery_web/live/ammo_group_live/show.ex:43
#: lib/cannery_web/live/pack_live/show.ex:43
#, elixir-autogen, elixir-format, fuzzy
msgid "Move Ammo"
msgstr "Déplacer munition"
@ -766,12 +759,12 @@ msgstr "Déplacer munition"
msgid "No ammo in this container"
msgstr "Aucun groupe de munition pour ce conteneur"
#: lib/cannery_web/live/ammo_group_live/show.ex:44
#: lib/cannery_web/live/pack_live/show.ex:44
#, elixir-autogen, elixir-format, fuzzy
msgid "Show Ammo"
msgstr "Montrer le type de munition"
#: lib/cannery_web/live/ammo_group_live/show.html.heex:118
#: lib/cannery_web/live/pack_live/show.html.heex:111
#, elixir-autogen, elixir-format, fuzzy
msgid "This ammo is not in a container"
msgstr "Ce groupe de munition nest pas dans un conteneur"
@ -800,25 +793,25 @@ msgid "Leave \"Uses left\" blank to make invite unlimited"
msgstr ""
"Laissez \"Utilisations restantes\" vide pour rendre l'invitation illimitée"
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:54
#: lib/cannery_web/components/core_components/pack_card.html.heex:51
#, elixir-autogen, elixir-format, fuzzy
msgid "Container:"
msgstr "Conteneur"
#: lib/cannery_web/live/ammo_group_live/index.html.heex:85
#: lib/cannery_web/live/ammo_type_live/index.html.heex:64
#: lib/cannery_web/live/ammo_type_live/show.html.heex:166
#: lib/cannery_web/live/pack_live/index.html.heex:87
#, elixir-autogen, elixir-format
msgid "Show used"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:202
#: lib/cannery_web/live/ammo_group_live/show.html.heex:19
#: lib/cannery_web/components/pack_table_component.ex:201
#: lib/cannery_web/live/pack_live/show.html.heex:19
#, elixir-autogen, elixir-format
msgid "%{percentage}%"
msgstr ""
#: lib/cannery_web/live/range_live/index.ex:153
#: lib/cannery_web/live/range_live/index.ex:154
#, elixir-autogen, elixir-format, fuzzy
msgid "Rounds shot: %{count}"
msgstr "Cartouches tirées"
@ -999,28 +992,28 @@ msgstr ""
msgid "Edit %{ammo_type_name}"
msgstr "Éditer %{name}"
#: lib/cannery_web/components/ammo_group_table_component.ex:251
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:17
#: lib/cannery_web/components/core_components/pack_card.html.heex:17
#: lib/cannery_web/components/pack_table_component.ex:250
#, elixir-autogen, elixir-format
msgid "Empty"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:81
#: lib/cannery_web/components/pack_table_component.ex:80
#, elixir-autogen, elixir-format
msgid "CPR"
msgstr ""
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:49
#: lib/cannery_web/components/core_components/pack_card.html.heex:46
#, elixir-autogen, elixir-format
msgid "CPR:"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:88
#: lib/cannery_web/components/pack_table_component.ex:87
#, elixir-autogen, elixir-format, fuzzy
msgid "Original Count"
msgstr "Nombre original:"
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:24
#: lib/cannery_web/components/core_components/pack_card.html.heex:21
#, elixir-autogen, elixir-format, fuzzy
msgid "Original Count:"
msgstr "Nombre original:"
@ -1030,34 +1023,34 @@ msgstr "Nombre original:"
msgid "Home"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:64
#: lib/cannery_web/components/pack_table_component.ex:63
#, elixir-autogen, elixir-format
msgid "Last used on"
msgstr ""
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:39
#: lib/cannery_web/components/core_components/pack_card.html.heex:36
#, elixir-autogen, elixir-format
msgid "Last used on:"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:182
#: lib/cannery_web/components/pack_table_component.ex:181
#, elixir-autogen, elixir-format
msgid "Never used"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:69
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:42
#: lib/cannery_web/components/pack_table_component.ex:68
#: lib/cannery_web/live/pack_live/form_component.html.heex:42
#, elixir-autogen, elixir-format
msgid "Purchased on"
msgstr ""
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:34
#: lib/cannery_web/live/ammo_group_live/show.html.heex:30
#: lib/cannery_web/components/core_components/pack_card.html.heex:31
#: lib/cannery_web/live/pack_live/show.html.heex:30
#, elixir-autogen, elixir-format
msgid "Purchased on:"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.ex:46
#: lib/cannery_web/live/pack_live/index.ex:51
#, elixir-autogen, elixir-format, fuzzy
msgid "Edit ammo"
msgstr "Éditer le type de munition"
@ -1073,7 +1066,7 @@ msgstr "Aucun type de munition"
msgid "Search catalog"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:79
#: lib/cannery_web/live/pack_live/index.html.heex:81
#, elixir-autogen, elixir-format, fuzzy
msgid "Search ammo"
msgstr ""
@ -1228,12 +1221,12 @@ msgstr ""
msgid "Really great weather"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:60
#: lib/cannery_web/components/ammo_type_table_component.ex:100
#: lib/cannery_web/components/container_table_component.ex:67
#: lib/cannery_web/components/move_ammo_group_component.ex:70
#: lib/cannery_web/components/move_pack_component.ex:68
#: lib/cannery_web/components/pack_table_component.ex:59
#: lib/cannery_web/components/shot_group_table_component.ex:45
#: lib/cannery_web/live/ammo_group_live/show.ex:94
#: lib/cannery_web/live/pack_live/show.ex:93
#, elixir-autogen, elixir-format
msgid "Actions"
msgstr ""
@ -1248,7 +1241,7 @@ msgstr ""
msgid "Log out"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:92
#: lib/cannery_web/components/pack_table_component.ex:91
#, elixir-autogen, elixir-format
msgid "Current Count"
msgstr ""
@ -1259,9 +1252,9 @@ msgstr ""
msgid "Close modal"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:56
#: lib/cannery_web/live/ammo_type_live/index.html.heex:35
#: lib/cannery_web/live/container_live/show.html.heex:103
#: lib/cannery_web/live/pack_live/index.html.heex:58
#: lib/cannery_web/live/range_live/index.html.heex:92
#, elixir-autogen, elixir-format
msgid "All"
@ -1333,7 +1326,7 @@ msgstr ""
msgid "Load grains:"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:29
#: lib/cannery_web/live/pack_live/index.html.heex:29
#, elixir-autogen, elixir-format, fuzzy
msgid "No ammo"
msgstr "Aucune munition"
@ -1343,11 +1336,11 @@ msgstr "Aucune munition"
msgid "None specified"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:59
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:25
#: lib/cannery_web/live/ammo_type_live/index.html.heex:38
#: lib/cannery_web/live/ammo_type_live/show.html.heex:58
#: lib/cannery_web/live/container_live/show.html.heex:106
#: lib/cannery_web/live/pack_live/index.html.heex:61
#: lib/cannery_web/live/range_live/index.html.heex:95
#, elixir-autogen, elixir-format
msgid "Pistol"
@ -1368,11 +1361,11 @@ msgstr "Type damorce"
msgid "Projectile"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:57
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:25
#: lib/cannery_web/live/ammo_type_live/index.html.heex:36
#: lib/cannery_web/live/ammo_type_live/show.html.heex:56
#: lib/cannery_web/live/container_live/show.html.heex:104
#: lib/cannery_web/live/pack_live/index.html.heex:59
#: lib/cannery_web/live/range_live/index.html.heex:93
#, elixir-autogen, elixir-format
msgid "Rifle"
@ -1422,11 +1415,11 @@ msgstr ""
msgid "Shot type:"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:58
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:25
#: lib/cannery_web/live/ammo_type_live/index.html.heex:37
#: lib/cannery_web/live/ammo_type_live/show.html.heex:54
#: lib/cannery_web/live/container_live/show.html.heex:105
#: lib/cannery_web/live/pack_live/index.html.heex:60
#: lib/cannery_web/live/range_live/index.html.heex:94
#, elixir-autogen, elixir-format
msgid "Shotgun"
@ -1464,3 +1457,14 @@ msgstr ""
#, elixir-autogen, elixir-format
msgid "Wadding:"
msgstr ""
#: lib/cannery_web/components/ammo_type_table_component.ex:150
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:21
#: lib/cannery_web/live/ammo_type_live/index.html.heex:29
#: lib/cannery_web/live/ammo_type_live/show.html.heex:48
#: lib/cannery_web/live/container_live/show.html.heex:97
#: lib/cannery_web/live/pack_live/index.html.heex:50
#: lib/cannery_web/live/range_live/index.html.heex:86
#, elixir-autogen, elixir-format
msgid "Class"
msgstr ""

View File

@ -162,22 +162,22 @@ msgstr ""
msgid "Tag could not be removed"
msgstr "Le tag na pas pu être retiré"
#: lib/cannery_web/live/ammo_group_live/form_component.ex:160
#: lib/cannery_web/live/pack_live/form_component.ex:159
#, elixir-autogen, elixir-format
msgid "Could not parse number of copies"
msgstr "Impossible d'analyser le nombre de copies"
#: lib/cannery_web/live/ammo_group_live/form_component.ex:150
#: lib/cannery_web/live/pack_live/form_component.ex:149
#, elixir-autogen, elixir-format
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:1114
#: lib/cannery/ammo.ex:1123
#, elixir-autogen, elixir-format
msgid "Invalid multiplier"
msgstr "Multiplicateur invalide"
#: lib/cannery/ammo/ammo_group.ex:92
#: lib/cannery/ammo/pack.ex:92
#, elixir-autogen, elixir-format
msgid "Please select an ammo type and container"
msgstr "Veuillez choisir un type de munitions et un conteneur"
@ -202,7 +202,7 @@ msgstr ""
msgid "Ammo left must be at least 0"
msgstr ""
#: lib/cannery/activity_log/shot_group.ex:122
#: lib/cannery/activity_log/shot_group.ex:119
#, elixir-autogen, elixir-format, fuzzy
msgid "Count can be at most %{count} shots"
msgstr "La quantité doit être inférieur à %{count}"

View File

@ -74,8 +74,8 @@ msgstr ""
msgid "Are you sure you want to delete %{name}?"
msgstr "Êtes-vous certain·e de supprimer %{name}?"
#: lib/cannery_web/live/ammo_group_live/index.html.heex:189
#: lib/cannery_web/live/ammo_group_live/show.html.heex:74
#: lib/cannery_web/live/pack_live/index.html.heex:187
#: lib/cannery_web/live/pack_live/show.html.heex:72
#, elixir-autogen, elixir-format
msgid "Are you sure you want to delete this ammo?"
msgstr "Êtes-vous certain·e de supprimer cette munition?"
@ -130,10 +130,10 @@ msgid "Please check your email to verify your account"
msgstr "Veuillez vérifier votre mél pour confirmer votre compte"
#: lib/cannery_web/components/add_shot_group_component.html.heex:59
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:85
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:351
#: lib/cannery_web/live/container_live/form_component.html.heex:59
#: lib/cannery_web/live/invite_live/form_component.html.heex:37
#: lib/cannery_web/live/pack_live/form_component.html.heex:85
#: lib/cannery_web/live/range_live/form_component.html.heex:47
#: lib/cannery_web/live/tag_live/form_component.html.heex:39
#, elixir-autogen, elixir-format
@ -177,13 +177,13 @@ msgstr "Tirs enregistré avec succès"
msgid "Are you sure you want to unstage this ammo?"
msgstr "Êtes-vous certain·e de vouloir désélectionner cette munition?"
#: lib/cannery_web/live/ammo_group_live/show.ex:159
#: lib/cannery_web/live/pack_live/show.ex:158
#: lib/cannery_web/live/range_live/index.html.heex:152
#, elixir-autogen, elixir-format
msgid "Are you sure you want to delete this shot record?"
msgstr "Êtes-vous certain·e de vouloir supprimer cet enregistrement de tir?"
#: lib/cannery_web/live/ammo_group_live/show.ex:81
#: lib/cannery_web/live/pack_live/show.ex:80
#: lib/cannery_web/live/range_live/index.ex:79
#, elixir-autogen, elixir-format
msgid "Shot records deleted succesfully"
@ -199,7 +199,7 @@ msgstr "Enregistrements de tir mis à jour avec succès"
msgid "%{email} confirmed successfully."
msgstr "%{email} confirmé avec succès."
#: lib/cannery_web/components/move_ammo_group_component.ex:54
#: lib/cannery_web/components/move_pack_component.ex:52
#, elixir-autogen, elixir-format
msgid "Ammo moved to %{name} successfully"
msgstr "Munition déplacée à %{name} avec succès"
@ -214,13 +214,13 @@ msgstr "Copié dans le presse-papier"
msgid "%{name} removed successfully"
msgstr "%{name} retiré avec succès"
#: lib/cannery_web/live/ammo_group_live/index.html.heex:10
#: lib/cannery_web/live/ammo_group_live/index.html.heex:20
#: lib/cannery_web/live/pack_live/index.html.heex:10
#: lib/cannery_web/live/pack_live/index.html.heex:20
#, elixir-autogen, elixir-format
msgid "You'll need to"
msgstr "Vous aurez besoin de"
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:78
#: lib/cannery_web/live/pack_live/form_component.html.heex:78
#, elixir-autogen, elixir-format
msgid "Creating..."
msgstr "Création en cours…"
@ -235,23 +235,23 @@ 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:89
#: lib/cannery_web/live/ammo_group_live/show.ex:55
#: lib/cannery_web/live/pack_live/index.ex:94
#: lib/cannery_web/live/pack_live/show.ex:55
#, elixir-autogen, elixir-format, fuzzy
msgid "Ammo deleted succesfully"
msgstr "Groupe de munition supprimé avec succès"
#: lib/cannery_web/live/range_live/index.ex:93
#: lib/cannery_web/live/range_live/index.ex:92
#, elixir-autogen, elixir-format, fuzzy
msgid "Ammo unstaged succesfully"
msgstr "Groupe de munition désélectionner avec succès"
#: lib/cannery_web/live/ammo_group_live/form_component.ex:126
#: lib/cannery_web/live/pack_live/form_component.ex:125
#, elixir-autogen, elixir-format, fuzzy
msgid "Ammo updated successfully"
msgstr "Groupe de munition mis à jour avec succès"
#: lib/cannery_web/live/ammo_group_live/form_component.ex:185
#: lib/cannery_web/live/pack_live/form_component.ex:184
#, elixir-autogen, elixir-format, fuzzy
msgid "Ammo added successfully"
msgid_plural "Ammo added successfully"

View File

@ -21,14 +21,14 @@ 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:54
#: lib/cannery_web/live/ammo_group_live/index.ex:62
#: lib/cannery_web/live/ammo_group_live/index.html.heex:38
#: lib/cannery_web/live/pack_live/index.ex:59
#: lib/cannery_web/live/pack_live/index.ex:67
#: lib/cannery_web/live/pack_live/index.html.heex:38
#, elixir-autogen, elixir-format
msgid "Add Ammo"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:34
#: lib/cannery_web/live/pack_live/index.html.heex:34
#, elixir-autogen, elixir-format
msgid "Add your first box!"
msgstr ""
@ -132,10 +132,10 @@ msgid "Reset password"
msgstr ""
#: lib/cannery_web/components/add_shot_group_component.html.heex:57
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:84
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:350
#: lib/cannery_web/live/container_live/form_component.html.heex:57
#: lib/cannery_web/live/invite_live/form_component.html.heex:35
#: lib/cannery_web/live/pack_live/form_component.html.heex:84
#: lib/cannery_web/live/range_live/form_component.html.heex:45
#: lib/cannery_web/live/tag_live/form_component.html.heex:37
#, elixir-autogen, elixir-format
@ -167,19 +167,19 @@ msgstr ""
msgid "Why not get some ready to shoot?"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:125
#: lib/cannery_web/live/ammo_group_live/show.html.heex:103
#: lib/cannery_web/live/pack_live/index.html.heex:127
#: lib/cannery_web/live/pack_live/show.html.heex:96
#: lib/cannery_web/live/range_live/index.html.heex:45
#, elixir-autogen, elixir-format
msgid "Record shots"
msgstr ""
#: lib/cannery_web/components/move_ammo_group_component.ex:90
#: lib/cannery_web/components/move_pack_component.ex:88
#, elixir-autogen, elixir-format
msgid "Add another container!"
msgstr ""
#: lib/cannery_web/components/move_ammo_group_component.ex:126
#: lib/cannery_web/components/move_pack_component.ex:124
#, elixir-autogen, elixir-format
msgid "Select"
msgstr ""
@ -189,12 +189,12 @@ msgstr ""
msgid "Copy to clipboard"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:14
#: lib/cannery_web/live/pack_live/index.html.heex:14
#, elixir-autogen, elixir-format
msgid "add a container first"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:77
#: lib/cannery_web/live/pack_live/form_component.html.heex:77
#, elixir-autogen, elixir-format
msgid "Create"
msgstr ""
@ -209,19 +209,19 @@ msgstr ""
msgid "Change language"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.html.heex:55
#: lib/cannery_web/live/pack_live/show.html.heex:55
#, elixir-autogen, elixir-format
msgid "View in Catalog"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:24
#: lib/cannery_web/live/pack_live/index.html.heex:24
#, elixir-autogen, elixir-format
msgid "add an ammo type first"
msgstr ""
#: lib/cannery_web/components/move_ammo_group_component.ex:80
#: lib/cannery_web/live/ammo_group_live/index.html.heex:142
#: lib/cannery_web/live/ammo_group_live/show.html.heex:96
#: lib/cannery_web/components/move_pack_component.ex:78
#: lib/cannery_web/live/pack_live/index.html.heex:144
#: lib/cannery_web/live/pack_live/show.html.heex:89
#, elixir-autogen, elixir-format
msgid "Move ammo"
msgstr ""
@ -231,13 +231,13 @@ msgstr ""
msgid "Set Unlimited"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.html.heex:89
#: lib/cannery_web/live/pack_live/show.html.heex:85
#: lib/cannery_web/live/range_live/index.html.heex:38
#, elixir-autogen, elixir-format
msgid "Stage for range"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.html.heex:88
#: lib/cannery_web/live/pack_live/show.html.heex:84
#: lib/cannery_web/live/range_live/index.html.heex:37
#, elixir-autogen, elixir-format
msgid "Unstage from range"
@ -287,7 +287,7 @@ msgstr ""
msgid "Delete invite for %{invite_name}"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.ex:161
#: lib/cannery_web/live/pack_live/show.ex:160
#: lib/cannery_web/live/range_live/index.html.heex:155
#, elixir-autogen, elixir-format
msgid "Delete shot record of %{shot_group_count} shots"
@ -311,18 +311,12 @@ msgstr ""
msgid "Edit %{tag_name}"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:164
#: lib/cannery_web/live/ammo_group_live/show.html.heex:62
#, elixir-autogen, elixir-format
msgid "Edit ammo group of %{ammo_group_count} bullets"
msgstr ""
#: lib/cannery_web/live/invite_live/index.html.heex:46
#, elixir-autogen, elixir-format
msgid "Edit invite for %{invite_name}"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.ex:146
#: lib/cannery_web/live/pack_live/show.ex:145
#, elixir-autogen, elixir-format
msgid "Edit shot group of %{shot_group_count} shots"
msgstr ""
@ -332,7 +326,7 @@ msgstr ""
msgid "Edit shot record of %{shot_group_count} shots"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:118
#: lib/cannery_web/live/pack_live/index.html.heex:120
#, elixir-autogen, elixir-format, fuzzy
msgid "Stage"
msgstr ""
@ -343,7 +337,7 @@ msgstr ""
msgid "Tag %{container_name}"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:117
#: lib/cannery_web/live/pack_live/index.html.heex:119
#, elixir-autogen, elixir-format
msgid "Unstage"
msgstr ""
@ -353,19 +347,25 @@ msgstr ""
msgid "View %{ammo_type_name}"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:176
#: lib/cannery_web/live/pack_live/index.html.heex:174
#, elixir-autogen, elixir-format, fuzzy
msgid "Clone ammo group of %{ammo_group_count} bullets"
msgid "Clone pack of %{pack_count} bullets"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:191
#: lib/cannery_web/live/ammo_group_live/show.html.heex:76
#: lib/cannery_web/live/pack_live/index.html.heex:189
#: lib/cannery_web/live/pack_live/show.html.heex:74
#, elixir-autogen, elixir-format, fuzzy
msgid "Delete ammo group of %{ammo_group_count} bullets"
msgid "Delete pack of %{pack_count} bullets"
msgstr ""
#: lib/cannery_web/live/pack_live/index.html.heex:164
#: lib/cannery_web/live/pack_live/show.html.heex:62
#, elixir-autogen, elixir-format, fuzzy
msgid "Edit pack of %{pack_count} bullets"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:152
#: lib/cannery_web/live/ammo_type_live/show.html.heex:206
#: lib/cannery_web/live/pack_live/index.html.heex:154
#, elixir-autogen, elixir-format, fuzzy
msgid "View ammo group of %{ammo_group_count} bullets"
msgid "View pack of %{pack_count} bullets"
msgstr ""

View File

@ -29,15 +29,15 @@ msgstr ""
#: lib/cannery_web/components/core_components/topbar.html.heex:58
#: lib/cannery_web/components/shot_group_table_component.ex:41
#: 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/pack_live/index.ex:75
#: lib/cannery_web/live/pack_live/index.ex:84
#: lib/cannery_web/live/pack_live/index.html.heex:3
#, elixir-autogen, elixir-format
msgid "Ammo"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:96
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:22
#: lib/cannery_web/components/pack_table_component.ex:95
#: lib/cannery_web/live/pack_live/form_component.html.heex:22
#, elixir-autogen, elixir-format
msgid "Ammo type"
msgstr ""
@ -88,9 +88,9 @@ msgstr ""
msgid "Case material"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:74
#: lib/cannery_web/components/move_ammo_group_component.ex:67
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:59
#: lib/cannery_web/components/move_pack_component.ex:65
#: lib/cannery_web/components/pack_table_component.ex:73
#: lib/cannery_web/live/pack_live/form_component.html.heex:59
#, elixir-autogen, elixir-format
msgid "Container"
msgstr ""
@ -109,14 +109,14 @@ msgstr ""
msgid "Corrosive"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:92
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:28
#: lib/cannery_web/components/pack_table_component.ex:91
#: lib/cannery_web/live/pack_live/form_component.html.heex:28
#, elixir-autogen, elixir-format
msgid "Count"
msgstr ""
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:16
#: lib/cannery_web/live/ammo_group_live/show.html.heex:8
#: lib/cannery_web/components/core_components/pack_card.html.heex:16
#: lib/cannery_web/live/pack_live/show.html.heex:8
#, elixir-autogen, elixir-format
msgid "Count:"
msgstr ""
@ -194,7 +194,7 @@ msgid "Keep me logged in for 60 days"
msgstr ""
#: lib/cannery_web/components/container_table_component.ex:47
#: lib/cannery_web/components/move_ammo_group_component.ex:69
#: lib/cannery_web/components/move_pack_component.ex:67
#: lib/cannery_web/live/container_live/form_component.html.heex:47
#, elixir-autogen, elixir-format
msgid "Location"
@ -260,7 +260,7 @@ msgstr ""
msgid "New Tag"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:92
#: lib/cannery_web/live/pack_live/index.html.heex:94
#, elixir-autogen, elixir-format
msgid "No Ammo"
msgstr ""
@ -290,15 +290,15 @@ msgstr ""
#: lib/cannery_web/components/add_shot_group_component.html.heex:38
#: lib/cannery_web/components/shot_group_table_component.ex:43
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:50
#: lib/cannery_web/live/ammo_group_live/show.ex:92
#: lib/cannery_web/live/pack_live/form_component.html.heex:50
#: lib/cannery_web/live/pack_live/show.ex:91
#: lib/cannery_web/live/range_live/form_component.html.heex:30
#, elixir-autogen, elixir-format
msgid "Notes"
msgstr ""
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:29
#: lib/cannery_web/live/ammo_group_live/show.html.heex:24
#: lib/cannery_web/components/core_components/pack_card.html.heex:26
#: lib/cannery_web/live/pack_live/show.html.heex:24
#, elixir-autogen, elixir-format
msgid "Notes:"
msgstr ""
@ -314,13 +314,13 @@ msgstr ""
msgid "Pressure"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:82
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:35
#: lib/cannery_web/components/pack_table_component.ex:81
#: lib/cannery_web/live/pack_live/form_component.html.heex:35
#, elixir-autogen, elixir-format
msgid "Price paid"
msgstr ""
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:44
#: lib/cannery_web/components/core_components/pack_card.html.heex:41
#, elixir-autogen, elixir-format
msgid "Price paid:"
msgstr ""
@ -362,7 +362,7 @@ msgstr ""
msgid "Steel"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.html.heex:113
#: lib/cannery_web/live/pack_live/show.html.heex:106
#, elixir-autogen, elixir-format
msgid "Stored in"
msgstr ""
@ -397,16 +397,9 @@ msgstr ""
msgid "Tracer"
msgstr ""
#: lib/cannery_web/components/ammo_type_table_component.ex:150
#: lib/cannery_web/components/container_table_component.ex:48
#: lib/cannery_web/components/move_ammo_group_component.ex:68
#: lib/cannery_web/live/ammo_group_live/index.html.heex:50
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:21
#: lib/cannery_web/live/ammo_type_live/index.html.heex:29
#: lib/cannery_web/live/ammo_type_live/show.html.heex:48
#: lib/cannery_web/components/move_pack_component.ex:66
#: lib/cannery_web/live/container_live/form_component.html.heex:39
#: lib/cannery_web/live/container_live/show.html.heex:97
#: lib/cannery_web/live/range_live/index.html.heex:86
#, elixir-autogen, elixir-format
msgid "Type"
msgstr ""
@ -437,8 +430,8 @@ msgstr ""
msgid "No tags for this container"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:78
#: lib/cannery_web/components/core_components/topbar.html.heex:66
#: lib/cannery_web/components/pack_table_component.ex:77
#, elixir-autogen, elixir-format
msgid "Range"
msgstr ""
@ -450,7 +443,7 @@ msgstr ""
#: lib/cannery_web/components/add_shot_group_component.html.heex:49
#: lib/cannery_web/components/shot_group_table_component.ex:44
#: lib/cannery_web/live/ammo_group_live/show.ex:93
#: lib/cannery_web/live/pack_live/show.ex:92
#: lib/cannery_web/live/range_live/form_component.html.heex:41
#, elixir-autogen, elixir-format
msgid "Date"
@ -467,12 +460,12 @@ 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:30
#: lib/cannery_web/live/pack_live/index.ex:35
#, elixir-autogen, elixir-format
msgid "Record shots"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.ex:42
#: lib/cannery_web/live/pack_live/show.ex:42
#: lib/cannery_web/live/range_live/index.ex:40
#, elixir-autogen, elixir-format
msgid "Edit Shot Records"
@ -496,7 +489,7 @@ msgid "Rounds left"
msgstr ""
#: lib/cannery_web/components/shot_group_table_component.ex:42
#: lib/cannery_web/live/ammo_group_live/show.ex:91
#: lib/cannery_web/live/pack_live/show.ex:90
#: lib/cannery_web/live/range_live/index.html.heex:69
#, elixir-autogen, elixir-format
msgid "Rounds shot"
@ -508,12 +501,12 @@ msgstr ""
msgid "Shot Records"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.ex:38
#: lib/cannery_web/live/pack_live/index.ex:43
#, elixir-autogen, elixir-format
msgid "Move ammo"
msgstr ""
#: lib/cannery_web/components/move_ammo_group_component.ex:85
#: lib/cannery_web/components/move_pack_component.ex:83
#, elixir-autogen, elixir-format
msgid "No other containers"
msgstr ""
@ -523,14 +516,14 @@ msgstr ""
msgid "Shot log"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:164
#: lib/cannery_web/components/ammo_group_table_component.ex:247
#: lib/cannery_web/components/ammo_type_table_component.ex:261
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:45
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:50
#: lib/cannery_web/live/ammo_group_live/show.html.heex:37
#: lib/cannery_web/live/ammo_group_live/show.html.heex:42
#: lib/cannery_web/components/core_components/pack_card.html.heex:42
#: lib/cannery_web/components/core_components/pack_card.html.heex:47
#: lib/cannery_web/components/pack_table_component.ex:163
#: lib/cannery_web/components/pack_table_component.ex:246
#: lib/cannery_web/live/ammo_type_live/show.html.heex:152
#: lib/cannery_web/live/pack_live/show.html.heex:37
#: lib/cannery_web/live/pack_live/show.html.heex:42
#, elixir-autogen, elixir-format
msgid "$%{amount}"
msgstr ""
@ -617,40 +610,40 @@ msgstr ""
msgid "Rounds:"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:161
#: lib/cannery_web/components/ammo_group_table_component.ex:243
#: lib/cannery_web/components/ammo_type_table_component.ex:260
#: lib/cannery_web/components/pack_table_component.ex:160
#: lib/cannery_web/components/pack_table_component.ex:242
#: lib/cannery_web/live/ammo_type_live/show.html.heex:156
#, elixir-autogen, elixir-format
msgid "No cost information"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:84
#: lib/cannery_web/components/pack_table_component.ex:83
#, elixir-autogen, elixir-format
msgid "% left"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.html.heex:41
#: lib/cannery_web/live/pack_live/show.html.heex:41
#, elixir-autogen, elixir-format
msgid "Current value:"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.html.heex:36
#: lib/cannery_web/live/pack_live/show.html.heex:36
#, elixir-autogen, elixir-format
msgid "Original cost:"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.html.heex:13
#: lib/cannery_web/live/pack_live/show.html.heex:13
#, elixir-autogen, elixir-format
msgid "Original count:"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.html.heex:18
#: lib/cannery_web/live/pack_live/show.html.heex:18
#, elixir-autogen, elixir-format
msgid "Percentage left:"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.html.heex:126
#: lib/cannery_web/live/pack_live/show.html.heex:119
#, elixir-autogen, elixir-format
msgid "Rounds used"
msgstr ""
@ -680,13 +673,13 @@ msgstr ""
msgid "Reset your password"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.ex:41
#: lib/cannery_web/live/pack_live/show.ex:41
#: lib/cannery_web/live/range_live/index.ex:32
#, elixir-autogen, elixir-format
msgid "Record Shots"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:69
#: lib/cannery_web/live/pack_live/form_component.html.heex:69
#, elixir-autogen, elixir-format
msgid "Copies"
msgstr ""
@ -745,12 +738,12 @@ msgstr ""
msgid "Catalog"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.ex:45
#: lib/cannery_web/live/pack_live/show.ex:45
#, elixir-autogen, elixir-format
msgid "Edit Ammo"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.ex:43
#: lib/cannery_web/live/pack_live/show.ex:43
#, elixir-autogen, elixir-format
msgid "Move Ammo"
msgstr ""
@ -760,12 +753,12 @@ msgstr ""
msgid "No ammo in this container"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.ex:44
#: lib/cannery_web/live/pack_live/show.ex:44
#, elixir-autogen, elixir-format
msgid "Show Ammo"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.html.heex:118
#: lib/cannery_web/live/pack_live/show.html.heex:111
#, elixir-autogen, elixir-format
msgid "This ammo is not in a container"
msgstr ""
@ -793,25 +786,25 @@ msgstr ""
msgid "Leave \"Uses left\" blank to make invite unlimited"
msgstr ""
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:54
#: lib/cannery_web/components/core_components/pack_card.html.heex:51
#, elixir-autogen, elixir-format
msgid "Container:"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:85
#: lib/cannery_web/live/ammo_type_live/index.html.heex:64
#: lib/cannery_web/live/ammo_type_live/show.html.heex:166
#: lib/cannery_web/live/pack_live/index.html.heex:87
#, elixir-autogen, elixir-format
msgid "Show used"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:202
#: lib/cannery_web/live/ammo_group_live/show.html.heex:19
#: lib/cannery_web/components/pack_table_component.ex:201
#: lib/cannery_web/live/pack_live/show.html.heex:19
#, elixir-autogen, elixir-format
msgid "%{percentage}%"
msgstr ""
#: lib/cannery_web/live/range_live/index.ex:153
#: lib/cannery_web/live/range_live/index.ex:154
#, elixir-autogen, elixir-format, fuzzy
msgid "Rounds shot: %{count}"
msgstr ""
@ -992,28 +985,28 @@ msgstr ""
msgid "Edit %{ammo_type_name}"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:251
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:17
#: lib/cannery_web/components/core_components/pack_card.html.heex:17
#: lib/cannery_web/components/pack_table_component.ex:250
#, elixir-autogen, elixir-format
msgid "Empty"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:81
#: lib/cannery_web/components/pack_table_component.ex:80
#, elixir-autogen, elixir-format
msgid "CPR"
msgstr ""
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:49
#: lib/cannery_web/components/core_components/pack_card.html.heex:46
#, elixir-autogen, elixir-format
msgid "CPR:"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:88
#: lib/cannery_web/components/pack_table_component.ex:87
#, elixir-autogen, elixir-format, fuzzy
msgid "Original Count"
msgstr ""
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:24
#: lib/cannery_web/components/core_components/pack_card.html.heex:21
#, elixir-autogen, elixir-format, fuzzy
msgid "Original Count:"
msgstr ""
@ -1023,34 +1016,34 @@ msgstr ""
msgid "Home"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:64
#: lib/cannery_web/components/pack_table_component.ex:63
#, elixir-autogen, elixir-format
msgid "Last used on"
msgstr ""
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:39
#: lib/cannery_web/components/core_components/pack_card.html.heex:36
#, elixir-autogen, elixir-format
msgid "Last used on:"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:182
#: lib/cannery_web/components/pack_table_component.ex:181
#, elixir-autogen, elixir-format
msgid "Never used"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:69
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:42
#: lib/cannery_web/components/pack_table_component.ex:68
#: lib/cannery_web/live/pack_live/form_component.html.heex:42
#, elixir-autogen, elixir-format
msgid "Purchased on"
msgstr ""
#: lib/cannery_web/components/core_components/ammo_group_card.html.heex:34
#: lib/cannery_web/live/ammo_group_live/show.html.heex:30
#: lib/cannery_web/components/core_components/pack_card.html.heex:31
#: lib/cannery_web/live/pack_live/show.html.heex:30
#, elixir-autogen, elixir-format
msgid "Purchased on:"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.ex:46
#: lib/cannery_web/live/pack_live/index.ex:51
#, elixir-autogen, elixir-format, fuzzy
msgid "Edit ammo"
msgstr ""
@ -1066,7 +1059,7 @@ msgstr ""
msgid "Search catalog"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:79
#: lib/cannery_web/live/pack_live/index.html.heex:81
#, elixir-autogen, elixir-format, fuzzy
msgid "Search ammo"
msgstr ""
@ -1219,12 +1212,12 @@ msgstr ""
msgid "Really great weather"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:60
#: lib/cannery_web/components/ammo_type_table_component.ex:100
#: lib/cannery_web/components/container_table_component.ex:67
#: lib/cannery_web/components/move_ammo_group_component.ex:70
#: lib/cannery_web/components/move_pack_component.ex:68
#: lib/cannery_web/components/pack_table_component.ex:59
#: lib/cannery_web/components/shot_group_table_component.ex:45
#: lib/cannery_web/live/ammo_group_live/show.ex:94
#: lib/cannery_web/live/pack_live/show.ex:93
#, elixir-autogen, elixir-format
msgid "Actions"
msgstr ""
@ -1239,7 +1232,7 @@ msgstr ""
msgid "Log out"
msgstr ""
#: lib/cannery_web/components/ammo_group_table_component.ex:92
#: lib/cannery_web/components/pack_table_component.ex:91
#, elixir-autogen, elixir-format
msgid "Current Count"
msgstr ""
@ -1250,9 +1243,9 @@ msgstr ""
msgid "Close modal"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:56
#: lib/cannery_web/live/ammo_type_live/index.html.heex:35
#: lib/cannery_web/live/container_live/show.html.heex:103
#: lib/cannery_web/live/pack_live/index.html.heex:58
#: lib/cannery_web/live/range_live/index.html.heex:92
#, elixir-autogen, elixir-format
msgid "All"
@ -1324,7 +1317,7 @@ msgstr ""
msgid "Load grains:"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:29
#: lib/cannery_web/live/pack_live/index.html.heex:29
#, elixir-autogen, elixir-format, fuzzy
msgid "No ammo"
msgstr ""
@ -1334,11 +1327,11 @@ msgstr ""
msgid "None specified"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:59
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:25
#: lib/cannery_web/live/ammo_type_live/index.html.heex:38
#: lib/cannery_web/live/ammo_type_live/show.html.heex:58
#: lib/cannery_web/live/container_live/show.html.heex:106
#: lib/cannery_web/live/pack_live/index.html.heex:61
#: lib/cannery_web/live/range_live/index.html.heex:95
#, elixir-autogen, elixir-format
msgid "Pistol"
@ -1359,11 +1352,11 @@ msgstr ""
msgid "Projectile"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:57
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:25
#: lib/cannery_web/live/ammo_type_live/index.html.heex:36
#: lib/cannery_web/live/ammo_type_live/show.html.heex:56
#: lib/cannery_web/live/container_live/show.html.heex:104
#: lib/cannery_web/live/pack_live/index.html.heex:59
#: lib/cannery_web/live/range_live/index.html.heex:93
#, elixir-autogen, elixir-format
msgid "Rifle"
@ -1413,11 +1406,11 @@ msgstr ""
msgid "Shot type:"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:58
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:25
#: lib/cannery_web/live/ammo_type_live/index.html.heex:37
#: lib/cannery_web/live/ammo_type_live/show.html.heex:54
#: lib/cannery_web/live/container_live/show.html.heex:105
#: lib/cannery_web/live/pack_live/index.html.heex:60
#: lib/cannery_web/live/range_live/index.html.heex:94
#, elixir-autogen, elixir-format
msgid "Shotgun"
@ -1455,3 +1448,14 @@ msgstr ""
#, elixir-autogen, elixir-format
msgid "Wadding:"
msgstr ""
#: lib/cannery_web/components/ammo_type_table_component.ex:150
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:21
#: lib/cannery_web/live/ammo_type_live/index.html.heex:29
#: lib/cannery_web/live/ammo_type_live/show.html.heex:48
#: lib/cannery_web/live/container_live/show.html.heex:97
#: lib/cannery_web/live/pack_live/index.html.heex:50
#: lib/cannery_web/live/range_live/index.html.heex:86
#, elixir-autogen, elixir-format
msgid "Class"
msgstr ""

View File

@ -161,22 +161,22 @@ msgstr ""
msgid "Tag could not be removed"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/form_component.ex:160
#: lib/cannery_web/live/pack_live/form_component.ex:159
#, elixir-autogen, elixir-format
msgid "Could not parse number of copies"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/form_component.ex:150
#: lib/cannery_web/live/pack_live/form_component.ex:149
#, elixir-autogen, elixir-format
msgid "Invalid number of copies, must be between 1 and %{max}. Was %{multiplier}"
msgstr ""
#: lib/cannery/ammo.ex:1114
#: lib/cannery/ammo.ex:1123
#, elixir-autogen, elixir-format
msgid "Invalid multiplier"
msgstr ""
#: lib/cannery/ammo/ammo_group.ex:92
#: lib/cannery/ammo/pack.ex:92
#, elixir-autogen, elixir-format
msgid "Please select an ammo type and container"
msgstr ""
@ -201,7 +201,7 @@ msgstr ""
msgid "Ammo left must be at least 0"
msgstr ""
#: lib/cannery/activity_log/shot_group.ex:122
#: lib/cannery/activity_log/shot_group.ex:119
#, elixir-autogen, elixir-format, fuzzy
msgid "Count can be at most %{count} shots"
msgstr ""

View File

@ -69,8 +69,8 @@ msgstr ""
msgid "Are you sure you want to delete %{name}?"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:189
#: lib/cannery_web/live/ammo_group_live/show.html.heex:74
#: lib/cannery_web/live/pack_live/index.html.heex:187
#: lib/cannery_web/live/pack_live/show.html.heex:72
#, elixir-autogen, elixir-format
msgid "Are you sure you want to delete this ammo?"
msgstr ""
@ -121,10 +121,10 @@ msgid "Please check your email to verify your account"
msgstr ""
#: lib/cannery_web/components/add_shot_group_component.html.heex:59
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:85
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:351
#: lib/cannery_web/live/container_live/form_component.html.heex:59
#: lib/cannery_web/live/invite_live/form_component.html.heex:37
#: lib/cannery_web/live/pack_live/form_component.html.heex:85
#: lib/cannery_web/live/range_live/form_component.html.heex:47
#: lib/cannery_web/live/tag_live/form_component.html.heex:39
#, elixir-autogen, elixir-format
@ -166,13 +166,13 @@ msgstr ""
msgid "Are you sure you want to unstage this ammo?"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.ex:159
#: lib/cannery_web/live/pack_live/show.ex:158
#: lib/cannery_web/live/range_live/index.html.heex:152
#, elixir-autogen, elixir-format
msgid "Are you sure you want to delete this shot record?"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.ex:81
#: lib/cannery_web/live/pack_live/show.ex:80
#: lib/cannery_web/live/range_live/index.ex:79
#, elixir-autogen, elixir-format
msgid "Shot records deleted succesfully"
@ -188,7 +188,7 @@ msgstr ""
msgid "%{email} confirmed successfully."
msgstr ""
#: lib/cannery_web/components/move_ammo_group_component.ex:54
#: lib/cannery_web/components/move_pack_component.ex:52
#, elixir-autogen, elixir-format
msgid "Ammo moved to %{name} successfully"
msgstr ""
@ -203,13 +203,13 @@ msgstr ""
msgid "%{name} removed successfully"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:10
#: lib/cannery_web/live/ammo_group_live/index.html.heex:20
#: lib/cannery_web/live/pack_live/index.html.heex:10
#: lib/cannery_web/live/pack_live/index.html.heex:20
#, elixir-autogen, elixir-format
msgid "You'll need to"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:78
#: lib/cannery_web/live/pack_live/form_component.html.heex:78
#, elixir-autogen, elixir-format
msgid "Creating..."
msgstr ""
@ -224,23 +224,23 @@ msgstr ""
msgid "Language updated successfully."
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.ex:89
#: lib/cannery_web/live/ammo_group_live/show.ex:55
#: lib/cannery_web/live/pack_live/index.ex:94
#: lib/cannery_web/live/pack_live/show.ex:55
#, elixir-autogen, elixir-format
msgid "Ammo deleted succesfully"
msgstr ""
#: lib/cannery_web/live/range_live/index.ex:93
#: lib/cannery_web/live/range_live/index.ex:92
#, elixir-autogen, elixir-format
msgid "Ammo unstaged succesfully"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/form_component.ex:126
#: lib/cannery_web/live/pack_live/form_component.ex:125
#, elixir-autogen, elixir-format
msgid "Ammo updated successfully"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/form_component.ex:185
#: lib/cannery_web/live/pack_live/form_component.ex:184
#, elixir-autogen, elixir-format
msgid "Ammo added successfully"
msgid_plural "Ammo added successfully"

View File

@ -58,8 +58,8 @@ msgstr ""
msgid "Are you sure you want to delete %{name}?"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:189
#: lib/cannery_web/live/ammo_group_live/show.html.heex:74
#: lib/cannery_web/live/pack_live/index.html.heex:187
#: lib/cannery_web/live/pack_live/show.html.heex:72
#, elixir-autogen, elixir-format
msgid "Are you sure you want to delete this ammo?"
msgstr ""
@ -110,10 +110,10 @@ msgid "Please check your email to verify your account"
msgstr ""
#: lib/cannery_web/components/add_shot_group_component.html.heex:59
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:85
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:351
#: lib/cannery_web/live/container_live/form_component.html.heex:59
#: lib/cannery_web/live/invite_live/form_component.html.heex:37
#: lib/cannery_web/live/pack_live/form_component.html.heex:85
#: lib/cannery_web/live/range_live/form_component.html.heex:47
#: lib/cannery_web/live/tag_live/form_component.html.heex:39
#, elixir-autogen, elixir-format
@ -155,13 +155,13 @@ msgstr ""
msgid "Are you sure you want to unstage this ammo?"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.ex:159
#: lib/cannery_web/live/pack_live/show.ex:158
#: lib/cannery_web/live/range_live/index.html.heex:152
#, elixir-autogen, elixir-format
msgid "Are you sure you want to delete this shot record?"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/show.ex:81
#: lib/cannery_web/live/pack_live/show.ex:80
#: lib/cannery_web/live/range_live/index.ex:79
#, elixir-autogen, elixir-format
msgid "Shot records deleted succesfully"
@ -177,7 +177,7 @@ msgstr ""
msgid "%{email} confirmed successfully."
msgstr ""
#: lib/cannery_web/components/move_ammo_group_component.ex:54
#: lib/cannery_web/components/move_pack_component.ex:52
#, elixir-autogen, elixir-format
msgid "Ammo moved to %{name} successfully"
msgstr ""
@ -192,13 +192,13 @@ msgstr ""
msgid "%{name} removed successfully"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:10
#: lib/cannery_web/live/ammo_group_live/index.html.heex:20
#: lib/cannery_web/live/pack_live/index.html.heex:10
#: lib/cannery_web/live/pack_live/index.html.heex:20
#, elixir-autogen, elixir-format
msgid "You'll need to"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:78
#: lib/cannery_web/live/pack_live/form_component.html.heex:78
#, elixir-autogen, elixir-format
msgid "Creating..."
msgstr ""
@ -213,23 +213,23 @@ msgstr ""
msgid "Language updated successfully."
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.ex:89
#: lib/cannery_web/live/ammo_group_live/show.ex:55
#: lib/cannery_web/live/pack_live/index.ex:94
#: lib/cannery_web/live/pack_live/show.ex:55
#, elixir-autogen, elixir-format
msgid "Ammo deleted succesfully"
msgstr ""
#: lib/cannery_web/live/range_live/index.ex:93
#: lib/cannery_web/live/range_live/index.ex:92
#, elixir-autogen, elixir-format
msgid "Ammo unstaged succesfully"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/form_component.ex:126
#: lib/cannery_web/live/pack_live/form_component.ex:125
#, elixir-autogen, elixir-format
msgid "Ammo updated successfully"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/form_component.ex:185
#: lib/cannery_web/live/pack_live/form_component.ex:184
#, elixir-autogen, elixir-format
msgid "Ammo added successfully"
msgid_plural "Ammo added successfully"

View File

@ -0,0 +1,117 @@
defmodule Cannery.Repo.Migrations.RenameTypeToClass do
use Ecto.Migration
def up do
drop index(:ammo_types, [:type])
flush()
rename table(:ammo_types), :type, to: :class
alter table(:ammo_types) do
remove_if_exists :search, :tsvector
end
flush()
create index(:ammo_types, [:class])
execute """
ALTER TABLE ammo_types
ADD COLUMN search tsvector
GENERATED ALWAYS AS (
setweight(to_tsvector('english', coalesce("name", '')), 'A') ||
setweight(to_tsvector('english', coalesce("desc", '')), 'B') ||
setweight(to_tsvector('english', coalesce("class", '')), 'B') ||
setweight(to_tsvector('english', coalesce("manufacturer", '')), 'C') ||
setweight(to_tsvector('english', coalesce("upc", '')), 'C') ||
setweight(to_tsvector('english', coalesce("bullet_type", '')), 'D') ||
setweight(to_tsvector('english', coalesce("bullet_core", '')), 'D') ||
setweight(to_tsvector('english', coalesce("cartridge", '')), 'D') ||
setweight(to_tsvector('english', coalesce("caliber", '')), 'D') ||
setweight(to_tsvector('english', coalesce("case_material", '')), 'D') ||
setweight(to_tsvector('english', coalesce("jacket_type", '')), 'D') ||
setweight(to_tsvector('english', immutable_to_string("muzzle_velocity", '')), 'D') ||
setweight(to_tsvector('english', coalesce("powder_type", '')), 'D') ||
setweight(to_tsvector('english', immutable_to_string("powder_grains_per_charge", '')), 'D') ||
setweight(to_tsvector('english', immutable_to_string("grains", '')), 'D') ||
setweight(to_tsvector('english', coalesce("pressure", '')), 'D') ||
setweight(to_tsvector('english', coalesce("primer_type", '')), 'D') ||
setweight(to_tsvector('english', coalesce("firing_type", '')), 'D') ||
setweight(to_tsvector('english', coalesce("wadding", '')), 'D') ||
setweight(to_tsvector('english', coalesce("shot_type", '')), 'D') ||
setweight(to_tsvector('english', coalesce("shot_material", '')), 'D') ||
setweight(to_tsvector('english', coalesce("shot_size", '')), 'D') ||
setweight(to_tsvector('english', coalesce("unfired_length", '')), 'D') ||
setweight(to_tsvector('english', coalesce("brass_height", '')), 'D') ||
setweight(to_tsvector('english', coalesce("chamber_size", '')), 'D') ||
setweight(to_tsvector('english', immutable_to_string("load_grains", '')), 'D') ||
setweight(to_tsvector('english', coalesce("shot_charge_weight", '')), 'D') ||
setweight(to_tsvector('english', coalesce("dram_equivalent", '')), 'D') ||
setweight(to_tsvector('english', boolean_to_string("tracer", 'tracer', '')), 'D') ||
setweight(to_tsvector('english', boolean_to_string("incendiary", 'incendiary', '')), 'D') ||
setweight(to_tsvector('english', boolean_to_string("blank", 'blank', '')), 'D') ||
setweight(to_tsvector('english', boolean_to_string("corrosive", 'corrosive', '')), 'D') ||
setweight(to_tsvector('english', coalesce("manufacturer", '')), 'D') ||
setweight(to_tsvector('english', coalesce("upc", '')), 'D')
) STORED
"""
end
def down do
drop index(:ammo_types, [:class])
flush()
rename table(:ammo_types), :class, to: :type
alter table(:ammo_types) do
remove_if_exists :search, :tsvector
end
flush()
create index(:ammo_types, [:type])
execute """
ALTER TABLE ammo_types
ADD COLUMN search TSVECTOR
GENERATED ALWAYS AS (
setweight(to_tsvector('english', coalesce("name", '')), 'A') ||
setweight(to_tsvector('english', coalesce("desc", '')), 'B') ||
setweight(to_tsvector('english', coalesce("type", '')), 'B') ||
setweight(to_tsvector('english', coalesce("manufacturer", '')), 'C') ||
setweight(to_tsvector('english', coalesce("upc", '')), 'C') ||
setweight(to_tsvector('english', coalesce("bullet_type", '')), 'D') ||
setweight(to_tsvector('english', coalesce("bullet_core", '')), 'D') ||
setweight(to_tsvector('english', coalesce("cartridge", '')), 'D') ||
setweight(to_tsvector('english', coalesce("caliber", '')), 'D') ||
setweight(to_tsvector('english', coalesce("case_material", '')), 'D') ||
setweight(to_tsvector('english', coalesce("jacket_type", '')), 'D') ||
setweight(to_tsvector('english', immutable_to_string("muzzle_velocity", '')), 'D') ||
setweight(to_tsvector('english', coalesce("powder_type", '')), 'D') ||
setweight(to_tsvector('english', immutable_to_string("powder_grains_per_charge", '')), 'D') ||
setweight(to_tsvector('english', immutable_to_string("grains", '')), 'D') ||
setweight(to_tsvector('english', coalesce("pressure", '')), 'D') ||
setweight(to_tsvector('english', coalesce("primer_type", '')), 'D') ||
setweight(to_tsvector('english', coalesce("firing_type", '')), 'D') ||
setweight(to_tsvector('english', coalesce("wadding", '')), 'D') ||
setweight(to_tsvector('english', coalesce("shot_type", '')), 'D') ||
setweight(to_tsvector('english', coalesce("shot_material", '')), 'D') ||
setweight(to_tsvector('english', coalesce("shot_size", '')), 'D') ||
setweight(to_tsvector('english', coalesce("unfired_length", '')), 'D') ||
setweight(to_tsvector('english', coalesce("brass_height", '')), 'D') ||
setweight(to_tsvector('english', coalesce("chamber_size", '')), 'D') ||
setweight(to_tsvector('english', immutable_to_string("load_grains", '')), 'D') ||
setweight(to_tsvector('english', coalesce("shot_charge_weight", '')), 'D') ||
setweight(to_tsvector('english', coalesce("dram_equivalent", '')), 'D') ||
setweight(to_tsvector('english', boolean_to_string("tracer", 'tracer', '')), 'D') ||
setweight(to_tsvector('english', boolean_to_string("incendiary", 'incendiary', '')), 'D') ||
setweight(to_tsvector('english', boolean_to_string("blank", 'blank', '')), 'D') ||
setweight(to_tsvector('english', boolean_to_string("corrosive", 'corrosive', '')), 'D') ||
setweight(to_tsvector('english', coalesce("manufacturer", '')), 'D') ||
setweight(to_tsvector('english', coalesce("upc", '')), 'D')
) STORED
"""
end
end

View File

@ -0,0 +1,51 @@
defmodule Cannery.Repo.Migrations.RenameAmmoGroupsToPacks do
use Ecto.Migration
def up do
drop index(:ammo_groups, [:user_id], where: "count = 0", name: :empty_ammo_groups_index)
drop index(:ammo_groups, [:user_id, :ammo_type_id])
drop index(:ammo_groups, [:user_id, :container_id])
drop index(:ammo_groups, [:ammo_type_id])
drop index(:ammo_groups, [:container_id])
drop index(:ammo_groups, [:user_id])
flush()
rename table(:ammo_groups), to: table(:packs)
flush()
create index(:packs, [:user_id], where: "count = 0", name: :empty_packs_index)
create index(:packs, [:user_id, :ammo_type_id])
create index(:packs, [:user_id, :container_id])
create index(:packs, [:ammo_type_id])
create index(:packs, [:container_id])
create index(:packs, [:user_id])
rename table(:shot_groups), :ammo_group_id, to: :pack_id
end
def down do
drop index(:packs, [:user_id], where: "count = 0", name: :empty_packs_index)
drop index(:packs, [:user_id, :ammo_type_id])
drop index(:packs, [:user_id, :container_id])
drop index(:packs, [:ammo_type_id])
drop index(:packs, [:container_id])
drop index(:packs, [:user_id])
flush()
rename table(:packs), to: table(:ammo_groups)
flush()
create index(:ammo_groups, [:user_id], where: "count = 0", name: :empty_ammo_groups_index)
create index(:ammo_groups, [:user_id, :ammo_type_id])
create index(:ammo_groups, [:user_id, :container_id])
create index(:ammo_groups, [:ammo_type_id])
create index(:ammo_groups, [:container_id])
create index(:ammo_groups, [:user_id])
rename table(:shot_groups), :pack_id, to: :ammo_group_id
end
end

View File

@ -11,11 +11,11 @@ defmodule Cannery.InvitesTest do
@moduletag :invites_test
@valid_attrs %{
"name" => "some name"
name: "some name"
}
@invalid_attrs %{
"name" => nil,
"token" => nil
name: nil,
token: nil
}
describe "invites" do
@ -57,7 +57,7 @@ defmodule Cannery.InvitesTest do
assert {:ok, _user} =
Accounts.register_user(
%{"email" => unique_user_email(), "password" => valid_user_password()},
%{email: unique_user_email(), password: valid_user_password()},
token
)
@ -65,7 +65,7 @@ defmodule Cannery.InvitesTest do
assert {:ok, _user} =
Accounts.register_user(
%{"email" => unique_user_email(), "password" => valid_user_password()},
%{email: unique_user_email(), password: valid_user_password()},
token
)
@ -81,13 +81,13 @@ defmodule Cannery.InvitesTest do
assert {:ok, _user} =
Accounts.register_user(
%{"email" => unique_user_email(), "password" => valid_user_password()},
%{email: unique_user_email(), password: valid_user_password()},
token
)
assert {:ok, _user} =
Accounts.register_user(
%{"email" => unique_user_email(), "password" => valid_user_password()},
%{email: unique_user_email(), password: valid_user_password()},
another_token
)
@ -97,7 +97,7 @@ defmodule Cannery.InvitesTest do
assert {:ok, _user} =
Accounts.register_user(
%{"email" => unique_user_email(), "password" => valid_user_password()},
%{email: unique_user_email(), password: valid_user_password()},
token
)
@ -138,21 +138,14 @@ defmodule Cannery.InvitesTest do
test "create_invite/1 with valid data creates an unlimited invite",
%{current_user: current_user} do
assert {:ok, %Invite{} = invite} =
Invites.create_invite(current_user, %{
"name" => "some name"
})
assert {:ok, %Invite{} = invite} = Invites.create_invite(current_user, %{name: "some name"})
assert invite.name == "some name"
end
test "create_invite/1 with valid data creates a limited invite",
%{current_user: current_user} do
assert {:ok, %Invite{} = invite} =
Invites.create_invite(current_user, %{
"name" => "some name",
"uses_left" => 10
})
Invites.create_invite(current_user, %{name: "some name", uses_left: 10})
assert invite.name == "some name"
assert invite.uses_left == 10
@ -168,7 +161,7 @@ defmodule Cannery.InvitesTest do
assert {:ok, %Invite{} = new_invite} =
Invites.update_invite(
invite,
%{"name" => "some updated name", "uses_left" => 5},
%{name: "some updated name", uses_left: 5},
current_user
)
@ -178,12 +171,12 @@ defmodule Cannery.InvitesTest do
test "update_invite/2 can set an invite to be unlimited",
%{invite: invite, current_user: current_user} do
{:ok, invite} = Invites.update_invite(invite, %{"uses_left" => 5}, current_user)
{:ok, invite} = Invites.update_invite(invite, %{uses_left: 5}, current_user)
assert {:ok, %Invite{} = new_invite} =
Invites.update_invite(
invite,
%{"name" => "some updated name", "uses_left" => nil},
%{name: "some updated name", uses_left: nil},
current_user
)

View File

@ -63,8 +63,7 @@ defmodule Cannery.AccountsTest do
end
test "validates email and password when given" do
{:error, changeset} =
Accounts.register_user(%{"email" => "not valid", "password" => "not valid"})
{:error, changeset} = Accounts.register_user(%{email: "not valid", password: "not valid"})
assert %{
email: ["must have the @ sign and no spaces"],
@ -74,26 +73,25 @@ defmodule Cannery.AccountsTest do
test "validates maximum values for email and password for security" do
too_long = String.duplicate("db", 100)
{:error, changeset} = Accounts.register_user(%{"email" => too_long, "password" => too_long})
{:error, changeset} = Accounts.register_user(%{email: too_long, password: too_long})
assert "should be at most 160 character(s)" in errors_on(changeset).email
assert "should be at most 80 character(s)" in errors_on(changeset).password
end
test "validates email uniqueness" do
%{email: email} = user_fixture()
{:error, changeset} = Accounts.register_user(%{"email" => email})
{:error, changeset} = Accounts.register_user(%{email: email})
assert "has already been taken" in errors_on(changeset).email
# Now try with the upper cased email too, to check that email case is ignored.
{:error, changeset} = Accounts.register_user(%{"email" => String.upcase(email)})
{:error, changeset} = Accounts.register_user(%{email: String.upcase(email)})
assert "has already been taken" in errors_on(changeset).email
end
test "registers users with a hashed password" do
email = unique_user_email()
{:ok, user} =
Accounts.register_user(%{"email" => email, "password" => valid_user_password()})
{:ok, user} = Accounts.register_user(%{email: email, password: valid_user_password()})
assert user.email == email
assert is_binary(user.hashed_password)
@ -103,11 +101,11 @@ defmodule Cannery.AccountsTest do
test "records used invite during registration" do
{:ok, %{id: invite_id, token: token}} =
admin_fixture() |> Invites.create_invite(%{"name" => "my invite"})
admin_fixture() |> Invites.create_invite(%{name: "my invite"})
assert {:ok, %{invite_id: ^invite_id}} =
Accounts.register_user(
%{"email" => unique_user_email(), "password" => valid_user_password()},
%{email: unique_user_email(), password: valid_user_password()},
token
)
end
@ -123,7 +121,7 @@ defmodule Cannery.AccountsTest do
email = unique_user_email()
password = valid_user_password()
changeset = Accounts.change_user_registration(%{"email" => email, "password" => password})
changeset = Accounts.change_user_registration(%{email: email, password: password})
assert changeset.valid?
assert get_change(changeset, :email) == email
@ -151,7 +149,7 @@ defmodule Cannery.AccountsTest do
test "validates email", %{user: user} do
{:error, changeset} =
Accounts.apply_user_email(user, valid_user_password(), %{"email" => "not valid"})
Accounts.apply_user_email(user, valid_user_password(), %{email: "not valid"})
assert %{email: ["must have the @ sign and no spaces"]} = errors_on(changeset)
end
@ -160,7 +158,7 @@ defmodule Cannery.AccountsTest do
too_long = String.duplicate("db", 100)
{:error, changeset} =
Accounts.apply_user_email(user, valid_user_password(), %{"email" => too_long})
Accounts.apply_user_email(user, valid_user_password(), %{email: too_long})
assert "should be at most 160 character(s)" in errors_on(changeset).email
end
@ -169,21 +167,21 @@ defmodule Cannery.AccountsTest do
%{email: email} = user_fixture()
{:error, changeset} =
Accounts.apply_user_email(user, valid_user_password(), %{"email" => email})
Accounts.apply_user_email(user, valid_user_password(), %{email: email})
assert "has already been taken" in errors_on(changeset).email
end
test "validates current password", %{user: user} do
{:error, changeset} =
Accounts.apply_user_email(user, "invalid", %{"email" => unique_user_email()})
Accounts.apply_user_email(user, "invalid", %{email: unique_user_email()})
assert %{current_password: ["is not valid"]} = errors_on(changeset)
end
test "applies the email without persisting it", %{user: user} do
email = unique_user_email()
{:ok, user} = Accounts.apply_user_email(user, valid_user_password(), %{"email" => email})
{:ok, user} = Accounts.apply_user_email(user, valid_user_password(), %{email: email})
assert user.email == email
assert Accounts.get_user!(user.id).email != email
end
@ -258,11 +256,7 @@ defmodule Cannery.AccountsTest do
end
test "allows fields to be set" do
changeset =
Accounts.change_user_password(%User{}, %{
"password" => "new valid password"
})
changeset = Accounts.change_user_password(%User{}, %{password: "new valid password"})
assert changeset.valid?
assert get_change(changeset, :password) == "new valid password"
assert is_nil(get_change(changeset, :hashed_password))
@ -277,8 +271,8 @@ defmodule Cannery.AccountsTest do
test "validates password", %{user: user} do
{:error, changeset} =
Accounts.update_user_password(user, valid_user_password(), %{
"password" => "not valid",
"password_confirmation" => "another"
password: "not valid",
password_confirmation: "another"
})
assert %{
@ -291,14 +285,14 @@ defmodule Cannery.AccountsTest do
too_long = String.duplicate("db", 100)
{:error, changeset} =
Accounts.update_user_password(user, valid_user_password(), %{"password" => too_long})
Accounts.update_user_password(user, valid_user_password(), %{password: too_long})
assert "should be at most 80 character(s)" in errors_on(changeset).password
end
test "validates current password", %{user: user} do
{:error, changeset} =
Accounts.update_user_password(user, "invalid", %{"password" => valid_user_password()})
Accounts.update_user_password(user, "invalid", %{password: valid_user_password()})
assert %{current_password: ["is not valid"]} = errors_on(changeset)
end
@ -306,7 +300,7 @@ defmodule Cannery.AccountsTest do
test "updates the password", %{user: user} do
{:ok, user} =
Accounts.update_user_password(user, valid_user_password(), %{
"password" => "new valid password"
password: "new valid password"
})
assert is_nil(user.password)
@ -318,7 +312,7 @@ defmodule Cannery.AccountsTest do
{:ok, _} =
Accounts.update_user_password(user, valid_user_password(), %{
"password" => "new valid password"
password: "new valid password"
})
refute Repo.get_by(UserToken, user_id: user.id)
@ -486,8 +480,8 @@ defmodule Cannery.AccountsTest do
test "validates password", %{user: user} do
{:error, changeset} =
Accounts.reset_user_password(user, %{
"password" => "not valid",
"password_confirmation" => "another"
password: "not valid",
password_confirmation: "another"
})
assert %{
@ -498,13 +492,12 @@ defmodule Cannery.AccountsTest do
test "validates maximum values for password for security", %{user: user} do
too_long = String.duplicate("db", 100)
{:error, changeset} = Accounts.reset_user_password(user, %{"password" => too_long})
{:error, changeset} = Accounts.reset_user_password(user, %{password: too_long})
assert "should be at most 80 character(s)" in errors_on(changeset).password
end
test "updates the password", %{user: user} do
{:ok, updated_user} =
Accounts.reset_user_password(user, %{"password" => "new valid password"})
{:ok, updated_user} = Accounts.reset_user_password(user, %{password: "new valid password"})
assert is_nil(updated_user.password)
assert Accounts.get_user_by_email_and_password(user.email, "new valid password")
@ -512,7 +505,7 @@ defmodule Cannery.AccountsTest do
test "deletes all tokens for the given user", %{user: user} do
_session_token = Accounts.generate_user_session_token(user)
{:ok, _user} = Accounts.reset_user_password(user, %{"password" => "new valid password"})
{:ok, _user} = Accounts.reset_user_password(user, %{password: "new valid password"})
refute Repo.get_by(UserToken, user_id: user.id)
end
end

View File

@ -5,12 +5,7 @@ defmodule Cannery.ActivityLogTest do
use Cannery.DataCase
import Cannery.Fixtures
alias Cannery.{
ActivityLog,
ActivityLog.ShotGroup,
Ammo
}
alias Cannery.{ActivityLog, ActivityLog.ShotGroup, Ammo}
@moduletag :activity_log_test
@ -20,24 +15,44 @@ defmodule Cannery.ActivityLogTest do
container = container_fixture(current_user)
ammo_type = ammo_type_fixture(current_user)
{1, [%{id: ammo_group_id} = ammo_group]} =
ammo_group_fixture(%{"count" => 25}, ammo_type, container, current_user)
{1, [%{id: pack_id} = pack]} =
pack_fixture(%{count: 25}, ammo_type, container, current_user)
shot_group =
%{"count" => 5, "date" => ~N[2022-02-13 03:17:00], "notes" => "some notes"}
|> shot_group_fixture(current_user, ammo_group)
%{count: 5, date: ~N[2022-02-13 03:17:00], notes: "some notes"}
|> shot_group_fixture(current_user, pack)
ammo_group = ammo_group_id |> Ammo.get_ammo_group!(current_user)
pack = pack_id |> Ammo.get_pack!(current_user)
[
current_user: current_user,
container: container,
ammo_type: ammo_type,
ammo_group: ammo_group,
pack: pack,
shot_group: shot_group
]
end
test "get_shot_record_count!/1 returns the correct amount of shot records",
%{pack: pack, current_user: current_user} do
assert ActivityLog.get_shot_record_count!(current_user) == 1
shot_group_fixture(%{count: 1, date: ~N[2022-02-13 03:17:00]}, current_user, pack)
assert ActivityLog.get_shot_record_count!(current_user) == 2
shot_group_fixture(%{count: 1, date: ~N[2022-02-13 03:17:00]}, current_user, pack)
assert ActivityLog.get_shot_record_count!(current_user) == 3
other_user = user_fixture()
assert ActivityLog.get_shot_record_count!(other_user) == 0
container = container_fixture(other_user)
ammo_type = ammo_type_fixture(other_user)
{1, [pack]} = pack_fixture(%{count: 25}, ammo_type, container, other_user)
shot_group_fixture(%{count: 1, date: ~N[2022-02-13 03:17:00]}, other_user, pack)
assert ActivityLog.get_shot_record_count!(other_user) == 1
end
test "get_shot_group!/2 returns the shot_group with given id",
%{shot_group: shot_group, current_user: current_user} do
assert ActivityLog.get_shot_group!(shot_group.id, current_user) == shot_group
@ -53,77 +68,76 @@ defmodule Cannery.ActivityLogTest do
end
test "create_shot_group/3 with valid data creates a shot_group",
%{current_user: current_user, ammo_group: ammo_group} do
valid_attrs = %{"count" => 10, "date" => ~D[2022-02-13], "notes" => "some notes"}
%{current_user: current_user, pack: pack} do
valid_attrs = %{count: 10, date: ~D[2022-02-13], notes: "some notes"}
assert {:ok, %ShotGroup{} = shot_group} =
ActivityLog.create_shot_group(valid_attrs, current_user, ammo_group)
ActivityLog.create_shot_group(valid_attrs, current_user, pack)
assert shot_group.count == 10
assert shot_group.date == ~D[2022-02-13]
assert shot_group.notes == "some notes"
end
test "create_shot_group/3 removes corresponding count from ammo group",
test "create_shot_group/3 removes corresponding count from pack",
%{
current_user: current_user,
ammo_group: %{id: ammo_group_id, count: org_count} = ammo_group
pack: %{id: pack_id, count: org_count} = pack
} do
valid_attrs = %{"count" => 10, "date" => ~D[2022-02-13], "notes" => "some notes"}
valid_attrs = %{count: 10, date: ~D[2022-02-13], notes: "some notes"}
assert {:ok, %ShotGroup{} = shot_group} =
ActivityLog.create_shot_group(valid_attrs, current_user, ammo_group)
ActivityLog.create_shot_group(valid_attrs, current_user, pack)
%{count: new_count} = ammo_group_id |> Ammo.get_ammo_group!(current_user)
%{count: new_count} = pack_id |> Ammo.get_pack!(current_user)
assert org_count - shot_group.count == new_count
assert new_count == 10
end
test "create_shot_group/3 does not remove more than ammo group amount",
%{current_user: current_user, ammo_group: %{id: ammo_group_id} = ammo_group} do
valid_attrs = %{"count" => 20, "date" => ~D[2022-02-13], "notes" => "some notes"}
test "create_shot_group/3 does not remove more tha pack amount",
%{current_user: current_user, pack: %{id: pack_id} = pack} do
valid_attrs = %{count: 20, date: ~D[2022-02-13], notes: "some notes"}
assert {:ok, %ShotGroup{}} =
ActivityLog.create_shot_group(valid_attrs, current_user, ammo_group)
assert {:ok, %ShotGroup{}} = ActivityLog.create_shot_group(valid_attrs, current_user, pack)
ammo_group = ammo_group_id |> Ammo.get_ammo_group!(current_user)
pack = pack_id |> Ammo.get_pack!(current_user)
assert ammo_group.count == 0
assert pack.count == 0
assert {:error, %Ecto.Changeset{}} =
ActivityLog.create_shot_group(%{"count" => 1}, current_user, ammo_group)
ActivityLog.create_shot_group(%{count: 1}, current_user, pack)
end
test "create_shot_group/3 with invalid data returns error changeset",
%{current_user: current_user, ammo_group: ammo_group} do
invalid_params = %{"count" => nil, "date" => nil, "notes" => nil}
%{current_user: current_user, pack: pack} do
invalid_params = %{count: nil, date: nil, notes: nil}
assert {:error, %Ecto.Changeset{}} =
ActivityLog.create_shot_group(invalid_params, current_user, ammo_group)
ActivityLog.create_shot_group(invalid_params, current_user, pack)
end
test "update_shot_group/3 with valid data updates the shot_group and ammo_group",
test "update_shot_group/3 with valid data updates the shot_group and pack",
%{
shot_group: shot_group,
ammo_group: %{id: ammo_group_id},
pack: %{id: pack_id},
current_user: current_user
} do
assert {:ok, %ShotGroup{} = shot_group} =
ActivityLog.update_shot_group(
shot_group,
%{
"count" => 10,
"date" => ~D[2022-02-13],
"notes" => "some updated notes"
count: 10,
date: ~D[2022-02-13],
notes: "some updated notes"
},
current_user
)
ammo_group = ammo_group_id |> Ammo.get_ammo_group!(current_user)
pack = pack_id |> Ammo.get_pack!(current_user)
assert shot_group.count == 10
assert ammo_group.count == 15
assert pack.count == 15
assert shot_group.date == ~D[2022-02-13]
assert shot_group.notes == "some updated notes"
@ -131,17 +145,17 @@ defmodule Cannery.ActivityLogTest do
ActivityLog.update_shot_group(
shot_group,
%{
"count" => 25,
"date" => ~D[2022-02-13],
"notes" => "some updated notes"
count: 25,
date: ~D[2022-02-13],
notes: "some updated notes"
},
current_user
)
ammo_group = ammo_group_id |> Ammo.get_ammo_group!(current_user)
pack = pack_id |> Ammo.get_pack!(current_user)
assert shot_group.count == 25
assert ammo_group.count == 0
assert pack.count == 0
end
test "update_shot_group/3 with invalid data returns error changeset",
@ -149,14 +163,14 @@ defmodule Cannery.ActivityLogTest do
assert {:error, %Ecto.Changeset{}} =
ActivityLog.update_shot_group(
shot_group,
%{"count" => 26, "date" => nil, "notes" => nil},
%{count: 26, date: nil, notes: nil},
current_user
)
assert {:error, %Ecto.Changeset{}} =
ActivityLog.update_shot_group(
shot_group,
%{"count" => -1, "date" => nil, "notes" => nil},
%{count: -1, date: nil, notes: nil},
current_user
)
@ -164,10 +178,10 @@ defmodule Cannery.ActivityLogTest do
end
test "delete_shot_group/2 deletes the shot_group and adds value back",
%{shot_group: shot_group, current_user: current_user, ammo_group: %{id: ammo_group_id}} do
%{shot_group: shot_group, current_user: current_user, pack: %{id: pack_id}} do
assert {:ok, %ShotGroup{}} = ActivityLog.delete_shot_group(shot_group, current_user)
assert %{count: 25} = ammo_group_id |> Ammo.get_ammo_group!(current_user)
assert %{count: 25} = pack_id |> Ammo.get_pack!(current_user)
assert_raise Ecto.NoResultsError, fn ->
ActivityLog.get_shot_group!(shot_group.id, current_user)
@ -175,123 +189,123 @@ defmodule Cannery.ActivityLogTest do
end
test "get_used_count/2 returns accurate used count", %{
ammo_group: ammo_group,
pack: pack,
ammo_type: ammo_type,
container: container,
current_user: current_user
} do
{1, [another_ammo_group]} = ammo_group_fixture(ammo_type, container, current_user)
assert 0 = another_ammo_group |> ActivityLog.get_used_count(current_user)
assert 5 = ammo_group |> ActivityLog.get_used_count(current_user)
{1, [another_pack]} = pack_fixture(ammo_type, container, current_user)
assert 0 = another_pack |> ActivityLog.get_used_count(current_user)
assert 5 = pack |> ActivityLog.get_used_count(current_user)
shot_group_fixture(%{"count" => 15}, current_user, ammo_group)
assert 20 = ammo_group |> ActivityLog.get_used_count(current_user)
shot_group_fixture(%{count: 15}, current_user, pack)
assert 20 = pack |> ActivityLog.get_used_count(current_user)
shot_group_fixture(%{"count" => 10}, current_user, ammo_group)
assert 30 = ammo_group |> ActivityLog.get_used_count(current_user)
shot_group_fixture(%{count: 10}, current_user, pack)
assert 30 = pack |> ActivityLog.get_used_count(current_user)
{1, [another_ammo_group]} = ammo_group_fixture(ammo_type, container, current_user)
assert 0 = another_ammo_group |> ActivityLog.get_used_count(current_user)
{1, [another_pack]} = pack_fixture(ammo_type, container, current_user)
assert 0 = another_pack |> ActivityLog.get_used_count(current_user)
end
test "get_used_counts/2 returns accurate used counts", %{
ammo_group: %{id: ammo_group_id} = ammo_group,
pack: %{id: pack_id} = pack,
ammo_type: ammo_type,
container: container,
current_user: current_user
} do
{1, [%{id: another_ammo_group_id} = another_ammo_group]} =
ammo_group_fixture(ammo_type, container, current_user)
{1, [%{id: another_pack_id} = another_pack]} =
pack_fixture(ammo_type, container, current_user)
assert %{ammo_group_id => 5} ==
[ammo_group, another_ammo_group] |> ActivityLog.get_used_counts(current_user)
assert %{pack_id => 5} ==
[pack, another_pack] |> ActivityLog.get_used_counts(current_user)
shot_group_fixture(%{"count" => 5}, current_user, another_ammo_group)
used_counts = [ammo_group, another_ammo_group] |> ActivityLog.get_used_counts(current_user)
assert %{^ammo_group_id => 5} = used_counts
assert %{^another_ammo_group_id => 5} = used_counts
shot_group_fixture(%{count: 5}, current_user, another_pack)
used_counts = [pack, another_pack] |> ActivityLog.get_used_counts(current_user)
assert %{^pack_id => 5} = used_counts
assert %{^another_pack_id => 5} = used_counts
shot_group_fixture(%{"count" => 15}, current_user, ammo_group)
used_counts = [ammo_group, another_ammo_group] |> ActivityLog.get_used_counts(current_user)
assert %{^ammo_group_id => 20} = used_counts
assert %{^another_ammo_group_id => 5} = used_counts
shot_group_fixture(%{count: 15}, current_user, pack)
used_counts = [pack, another_pack] |> ActivityLog.get_used_counts(current_user)
assert %{^pack_id => 20} = used_counts
assert %{^another_pack_id => 5} = used_counts
shot_group_fixture(%{"count" => 10}, current_user, ammo_group)
used_counts = [ammo_group, another_ammo_group] |> ActivityLog.get_used_counts(current_user)
assert %{^ammo_group_id => 30} = used_counts
assert %{^another_ammo_group_id => 5} = used_counts
shot_group_fixture(%{count: 10}, current_user, pack)
used_counts = [pack, another_pack] |> ActivityLog.get_used_counts(current_user)
assert %{^pack_id => 30} = used_counts
assert %{^another_pack_id => 5} = used_counts
end
test "get_last_used_date/2 returns accurate used count", %{
ammo_group: ammo_group,
pack: pack,
ammo_type: ammo_type,
container: container,
shot_group: %{date: date},
current_user: current_user
} do
{1, [another_ammo_group]} = ammo_group_fixture(ammo_type, container, current_user)
assert another_ammo_group |> ActivityLog.get_last_used_date(current_user) |> is_nil()
assert ^date = ammo_group |> ActivityLog.get_last_used_date(current_user)
{1, [another_pack]} = pack_fixture(ammo_type, container, current_user)
assert another_pack |> ActivityLog.get_last_used_date(current_user) |> is_nil()
assert ^date = pack |> ActivityLog.get_last_used_date(current_user)
%{date: date} = shot_group_fixture(%{"date" => ~D[2022-11-10]}, current_user, ammo_group)
assert ^date = ammo_group |> ActivityLog.get_last_used_date(current_user)
%{date: date} = shot_group_fixture(%{date: ~D[2022-11-10]}, current_user, pack)
assert ^date = pack |> ActivityLog.get_last_used_date(current_user)
%{date: date} = shot_group_fixture(%{"date" => ~D[2022-11-11]}, current_user, ammo_group)
assert ^date = ammo_group |> ActivityLog.get_last_used_date(current_user)
%{date: date} = shot_group_fixture(%{date: ~D[2022-11-11]}, current_user, pack)
assert ^date = pack |> ActivityLog.get_last_used_date(current_user)
end
test "get_last_used_dates/2 returns accurate used counts", %{
ammo_group: %{id: ammo_group_id} = ammo_group,
pack: %{id: pack_id} = pack,
ammo_type: ammo_type,
container: container,
shot_group: %{date: date},
current_user: current_user
} do
{1, [%{id: another_ammo_group_id} = another_ammo_group]} =
ammo_group_fixture(ammo_type, container, current_user)
{1, [%{id: another_pack_id} = another_pack]} =
pack_fixture(ammo_type, container, current_user)
# unset date
assert %{ammo_group_id => date} ==
[ammo_group, another_ammo_group] |> ActivityLog.get_last_used_dates(current_user)
assert %{pack_id => date} ==
[pack, another_pack] |> ActivityLog.get_last_used_dates(current_user)
shot_group_fixture(%{"date" => ~D[2022-11-09]}, current_user, another_ammo_group)
shot_group_fixture(%{date: ~D[2022-11-09]}, current_user, another_pack)
# setting initial date
last_used_shot_groups =
[ammo_group, another_ammo_group] |> ActivityLog.get_last_used_dates(current_user)
[pack, another_pack] |> ActivityLog.get_last_used_dates(current_user)
assert %{^ammo_group_id => ^date} = last_used_shot_groups
assert %{^another_ammo_group_id => ~D[2022-11-09]} = last_used_shot_groups
assert %{^pack_id => ^date} = last_used_shot_groups
assert %{^another_pack_id => ~D[2022-11-09]} = last_used_shot_groups
# setting another date
shot_group_fixture(%{"date" => ~D[2022-11-10]}, current_user, ammo_group)
shot_group_fixture(%{date: ~D[2022-11-10]}, current_user, pack)
last_used_shot_groups =
[ammo_group, another_ammo_group] |> ActivityLog.get_last_used_dates(current_user)
[pack, another_pack] |> ActivityLog.get_last_used_dates(current_user)
assert %{^ammo_group_id => ~D[2022-11-10]} = last_used_shot_groups
assert %{^another_ammo_group_id => ~D[2022-11-09]} = last_used_shot_groups
assert %{^pack_id => ~D[2022-11-10]} = last_used_shot_groups
assert %{^another_pack_id => ~D[2022-11-09]} = last_used_shot_groups
# setting yet another date
shot_group_fixture(%{"date" => ~D[2022-11-11]}, current_user, ammo_group)
shot_group_fixture(%{date: ~D[2022-11-11]}, current_user, pack)
last_used_shot_groups =
[ammo_group, another_ammo_group] |> ActivityLog.get_last_used_dates(current_user)
[pack, another_pack] |> ActivityLog.get_last_used_dates(current_user)
assert %{^ammo_group_id => ~D[2022-11-11]} = last_used_shot_groups
assert %{^another_ammo_group_id => ~D[2022-11-09]} = last_used_shot_groups
assert %{^pack_id => ~D[2022-11-11]} = last_used_shot_groups
assert %{^another_pack_id => ~D[2022-11-09]} = last_used_shot_groups
end
test "get_used_count_for_ammo_type/2 gets accurate used round count for ammo type",
%{ammo_type: ammo_type, ammo_group: ammo_group, current_user: current_user} do
%{ammo_type: ammo_type, pack: pack, current_user: current_user} do
another_ammo_type = ammo_type_fixture(current_user)
assert 0 = another_ammo_type |> ActivityLog.get_used_count_for_ammo_type(current_user)
assert 5 = ammo_type |> ActivityLog.get_used_count_for_ammo_type(current_user)
shot_group_fixture(%{"count" => 5}, current_user, ammo_group)
shot_group_fixture(%{count: 5}, current_user, pack)
assert 10 = ammo_type |> ActivityLog.get_used_count_for_ammo_type(current_user)
shot_group_fixture(%{"count" => 1}, current_user, ammo_group)
shot_group_fixture(%{count: 1}, current_user, pack)
assert 11 = ammo_type |> ActivityLog.get_used_count_for_ammo_type(current_user)
end
@ -302,14 +316,14 @@ defmodule Cannery.ActivityLogTest do
} do
# testing unused ammo type
%{id: another_ammo_type_id} = another_ammo_type = ammo_type_fixture(current_user)
{1, [ammo_group]} = ammo_group_fixture(another_ammo_type, container, current_user)
{1, [pack]} = pack_fixture(another_ammo_type, container, current_user)
assert %{ammo_type_id => 5} ==
[ammo_type, another_ammo_type]
|> ActivityLog.get_used_count_for_ammo_types(current_user)
# use generated ammo group
shot_group_fixture(%{"count" => 5}, current_user, ammo_group)
# use generated pack
shot_group_fixture(%{count: 5}, current_user, pack)
used_counts =
[ammo_type, another_ammo_type] |> ActivityLog.get_used_count_for_ammo_types(current_user)
@ -317,8 +331,8 @@ defmodule Cannery.ActivityLogTest do
assert %{^ammo_type_id => 5} = used_counts
assert %{^another_ammo_type_id => 5} = used_counts
# use generated ammo group again
shot_group_fixture(%{"count" => 1}, current_user, ammo_group)
# use generated pack again
shot_group_fixture(%{count: 1}, current_user, pack)
used_counts =
[ammo_type, another_ammo_type] |> ActivityLog.get_used_count_for_ammo_types(current_user)
@ -333,13 +347,13 @@ defmodule Cannery.ActivityLogTest do
current_user = user_fixture()
container = container_fixture(current_user)
ammo_type = ammo_type_fixture(current_user)
{1, [ammo_group]} = ammo_group_fixture(ammo_type, container, current_user)
{1, [pack]} = pack_fixture(ammo_type, container, current_user)
[
current_user: current_user,
container: container,
ammo_type: ammo_type,
ammo_group: ammo_group
pack: pack
]
end
@ -348,23 +362,23 @@ defmodule Cannery.ActivityLogTest do
other_user = user_fixture()
other_container = container_fixture(other_user)
for type <- ["rifle", "shotgun", "pistol"] do
other_ammo_type = ammo_type_fixture(%{"type" => type}, other_user)
{1, [other_ammo_group]} = ammo_group_fixture(other_ammo_type, other_container, other_user)
shot_group_fixture(other_user, other_ammo_group)
for class <- ["rifle", "shotgun", "pistol"] do
other_ammo_type = ammo_type_fixture(%{class: class}, other_user)
{1, [other_pack]} = pack_fixture(other_ammo_type, other_container, other_user)
shot_group_fixture(other_user, other_pack)
end
rifle_ammo_type = ammo_type_fixture(%{"type" => "rifle"}, current_user)
{1, [rifle_ammo_group]} = ammo_group_fixture(rifle_ammo_type, container, current_user)
rifle_shot_group = shot_group_fixture(current_user, rifle_ammo_group)
rifle_ammo_type = ammo_type_fixture(%{class: :rifle}, current_user)
{1, [rifle_pack]} = pack_fixture(rifle_ammo_type, container, current_user)
rifle_shot_group = shot_group_fixture(current_user, rifle_pack)
shotgun_ammo_type = ammo_type_fixture(%{"type" => "shotgun"}, current_user)
{1, [shotgun_ammo_group]} = ammo_group_fixture(shotgun_ammo_type, container, current_user)
shotgun_shot_group = shot_group_fixture(current_user, shotgun_ammo_group)
shotgun_ammo_type = ammo_type_fixture(%{class: :shotgun}, current_user)
{1, [shotgun_pack]} = pack_fixture(shotgun_ammo_type, container, current_user)
shotgun_shot_group = shot_group_fixture(current_user, shotgun_pack)
pistol_ammo_type = ammo_type_fixture(%{"type" => "pistol"}, current_user)
{1, [pistol_ammo_group]} = ammo_group_fixture(pistol_ammo_type, container, current_user)
pistol_shot_group = shot_group_fixture(current_user, pistol_ammo_group)
pistol_ammo_type = ammo_type_fixture(%{class: :pistol}, current_user)
{1, [pistol_pack]} = pack_fixture(pistol_ammo_type, container, current_user)
pistol_shot_group = shot_group_fixture(current_user, pistol_pack)
assert [^rifle_shot_group] = ActivityLog.list_shot_groups(:rifle, current_user)
assert [^shotgun_shot_group] = ActivityLog.list_shot_groups(:shotgun, current_user)
@ -385,37 +399,35 @@ defmodule Cannery.ActivityLogTest do
test "list_shot_groups/3 returns relevant shot_groups for a search", %{
ammo_type: ammo_type,
ammo_group: ammo_group,
pack: pack,
container: container,
current_user: current_user
} do
shot_group_a = shot_group_fixture(%{"notes" => "amazing"}, current_user, ammo_group)
shot_group_a = shot_group_fixture(%{notes: "amazing"}, current_user, pack)
{1, [another_ammo_group]} =
ammo_group_fixture(%{"notes" => "stupendous"}, ammo_type, container, current_user)
{1, [another_pack]} =
pack_fixture(%{notes: "stupendous"}, ammo_type, container, current_user)
shot_group_b = shot_group_fixture(current_user, another_ammo_group)
shot_group_b = shot_group_fixture(current_user, another_pack)
another_ammo_type = ammo_type_fixture(%{"name" => "fabulous ammo"}, current_user)
another_ammo_type = ammo_type_fixture(%{name: "fabulous ammo"}, current_user)
{1, [yet_another_ammo_group]} =
ammo_group_fixture(another_ammo_type, container, current_user)
{1, [yet_another_pack]} = pack_fixture(another_ammo_type, container, current_user)
shot_group_c = shot_group_fixture(current_user, yet_another_ammo_group)
shot_group_c = shot_group_fixture(current_user, yet_another_pack)
another_user = user_fixture()
another_container = container_fixture(another_user)
another_ammo_type = ammo_type_fixture(another_user)
{1, [another_ammo_group]} =
ammo_group_fixture(another_ammo_type, another_container, another_user)
{1, [another_pack]} = pack_fixture(another_ammo_type, another_container, another_user)
_shouldnt_return = shot_group_fixture(another_user, another_ammo_group)
_shouldnt_return = shot_group_fixture(another_user, another_pack)
# notes
assert ActivityLog.list_shot_groups("amazing", :all, current_user) == [shot_group_a]
# ammo group attributes
# pack attributes
assert ActivityLog.list_shot_groups("stupendous", :all, current_user) == [shot_group_b]
# ammo type attributes

File diff suppressed because it is too large Load Diff

View File

@ -10,37 +10,37 @@ defmodule Cannery.ContainersTest do
@moduletag :containers_test
@valid_attrs %{
"desc" => "some desc",
"location" => "some location",
"name" => "some name",
"type" => "some type"
desc: "some desc",
location: "some location",
name: "some name",
type: "some type"
}
@update_attrs %{
"desc" => "some updated desc",
"location" => "some updated location",
"name" => "some updated name",
"type" => "some updated type"
desc: "some updated desc",
location: "some updated location",
name: "some updated name",
type: "some updated type"
}
@invalid_attrs %{
"desc" => nil,
"location" => nil,
"name" => nil,
"type" => nil
desc: nil,
location: nil,
name: nil,
type: nil
}
@valid_tag_attrs %{
"bg_color" => "#100000",
"name" => "some name",
"text_color" => "#000000"
bg_color: "#100000",
name: "some name",
text_color: "#000000"
}
@update_tag_attrs %{
"bg_color" => "#100001",
"name" => "some updated name",
"text_color" => "#000001"
bg_color: "#100001",
name: "some updated name",
text_color: "#000001"
}
@invalid_tag_attrs %{
"bg_color" => nil,
"name" => nil,
"text_color" => nil
bg_color: nil,
name: nil,
text_color: nil
}
describe "containers" do
@ -57,25 +57,24 @@ defmodule Cannery.ContainersTest do
test "list_containers/2 returns relevant containers for a user",
%{current_user: current_user} do
container_a = container_fixture(%{"name" => "my cool container"}, current_user)
container_b = container_fixture(%{"desc" => "a fascinating description"}, current_user)
container_a = container_fixture(%{name: "my cool container"}, current_user)
container_b = container_fixture(%{desc: "a fascinating description"}, current_user)
%{id: container_c_id} =
container_c = container_fixture(%{"location" => "a secret place"}, current_user)
container_c = container_fixture(%{location: "a secret place"}, current_user)
tag = tag_fixture(%{"name" => "stupendous tag"}, current_user)
tag = tag_fixture(%{name: "stupendous tag"}, current_user)
Containers.add_tag!(container_c, tag, current_user)
container_c = container_c_id |> Containers.get_container!(current_user)
%{id: container_d_id} =
container_d = container_fixture(%{"type" => "musty old box"}, current_user)
container_d = container_fixture(%{type: "musty old box"}, current_user)
tag = tag_fixture(%{"name" => "amazing tag"}, current_user)
tag = tag_fixture(%{name: "amazing tag"}, current_user)
Containers.add_tag!(container_d, tag, current_user)
container_d = container_d_id |> Containers.get_container!(current_user)
_shouldnt_return =
container_fixture(%{"name" => "another person's container"}, user_fixture())
_shouldnt_return = container_fixture(%{name: "another person's container"}, user_fixture())
# attributes
assert Containers.list_containers("cool", current_user) == [container_a]
@ -109,7 +108,7 @@ defmodule Cannery.ContainersTest do
test "create_container/2 with valid data creates a container", %{current_user: current_user} do
assert {:ok, %Container{} = container} =
@valid_attrs |> Containers.create_container(current_user)
Containers.create_container(@valid_attrs, current_user)
assert container.desc == "some desc"
assert container.location == "some location"
@ -120,7 +119,7 @@ defmodule Cannery.ContainersTest do
test "create_container/2 with invalid data returns error changeset",
%{current_user: current_user} do
assert {:error, %Changeset{}} = @invalid_attrs |> Containers.create_container(current_user)
assert {:error, %Changeset{}} = Containers.create_container(@invalid_attrs, current_user)
end
test "update_container/3 with valid data updates the container",
@ -163,15 +162,10 @@ defmodule Cannery.ContainersTest do
end
test "list_tags/2 returns relevant tags for a user", %{current_user: current_user} do
tag_a = tag_fixture(%{"name" => "bullets"}, current_user)
tag_b = tag_fixture(%{"name" => "hollows"}, current_user)
tag_a = tag_fixture(%{name: "bullets"}, current_user)
tag_b = tag_fixture(%{name: "hollows"}, current_user)
_shouldnt_return =
%{
"name" => "bullet",
"desc" => "pews brass shell"
}
|> tag_fixture(user_fixture())
tag_fixture(%{name: "bullet", desc: "pews brass shell"}, user_fixture())
# name
assert Containers.list_tags("bullet", current_user) == [tag_a]

View File

@ -15,13 +15,13 @@ defmodule CanneryWeb.ExportControllerTest do
container = container_fixture(current_user)
tag = tag_fixture(current_user)
Containers.add_tag!(container, tag, current_user)
{1, [ammo_group]} = ammo_group_fixture(ammo_type, container, current_user)
shot_group = shot_group_fixture(current_user, ammo_group)
ammo_group = ammo_group |> Repo.reload!()
{1, [pack]} = pack_fixture(ammo_type, container, current_user)
shot_group = shot_group_fixture(current_user, pack)
pack = pack |> Repo.reload!()
%{
ammo_type: ammo_type,
ammo_group: ammo_group,
pack: pack,
container: container,
shot_group: shot_group,
tag: tag
@ -36,24 +36,24 @@ defmodule CanneryWeb.ExportControllerTest do
current_user: current_user,
container: container,
ammo_type: ammo_type,
ammo_group: ammo_group,
pack: pack,
shot_group: shot_group,
tag: tag
} do
conn = get(conn, Routes.export_path(conn, :export, :json))
ideal_ammo_group = %{
"ammo_type_id" => ammo_group.ammo_type_id,
"container_id" => ammo_group.container_id,
"count" => ammo_group.count,
"id" => ammo_group.id,
"notes" => ammo_group.notes,
"price_paid" => ammo_group.price_paid,
"staged" => ammo_group.staged,
"used_count" => ammo_group |> ActivityLog.get_used_count(current_user),
"original_count" => ammo_group |> Ammo.get_original_count(current_user),
"cpr" => ammo_group |> Ammo.get_cpr(current_user),
"percentage_remaining" => ammo_group |> Ammo.get_percentage_remaining(current_user)
ideal_pack = %{
"ammo_type_id" => pack.ammo_type_id,
"container_id" => pack.container_id,
"count" => pack.count,
"id" => pack.id,
"notes" => pack.notes,
"price_paid" => pack.price_paid,
"staged" => pack.staged,
"used_count" => pack |> ActivityLog.get_used_count(current_user),
"original_count" => pack |> Ammo.get_original_count(current_user),
"cpr" => pack |> Ammo.get_cpr(current_user),
"percentage_remaining" => pack |> Ammo.get_percentage_remaining(current_user)
}
ideal_ammo_type = %{
@ -82,9 +82,8 @@ defmodule CanneryWeb.ExportControllerTest do
"average_cost" => ammo_type |> Ammo.get_average_cost_for_ammo_type(current_user),
"round_count" => ammo_type |> Ammo.get_round_count_for_ammo_type(current_user),
"used_count" => ammo_type |> ActivityLog.get_used_count_for_ammo_type(current_user),
"ammo_group_count" => ammo_type |> Ammo.get_ammo_groups_count_for_type(current_user),
"total_ammo_group_count" =>
ammo_type |> Ammo.get_ammo_groups_count_for_type(current_user, true)
"pack_count" => ammo_type |> Ammo.get_packs_count_for_type(current_user),
"total_pack_count" => ammo_type |> Ammo.get_packs_count_for_type(current_user, true)
}
ideal_container = %{
@ -101,13 +100,12 @@ defmodule CanneryWeb.ExportControllerTest do
}
],
"type" => container.type,
"ammo_group_count" =>
container |> Ammo.get_ammo_groups_count_for_container!(current_user),
"pack_count" => container |> Ammo.get_packs_count_for_container!(current_user),
"round_count" => container |> Ammo.get_round_count_for_container!(current_user)
}
ideal_shot_group = %{
"ammo_group_id" => shot_group.ammo_group_id,
"pack_id" => shot_group.pack_id,
"count" => shot_group.count,
"date" => to_string(shot_group.date),
"id" => shot_group.id,
@ -126,7 +124,7 @@ defmodule CanneryWeb.ExportControllerTest do
}
json_resp = conn |> json_response(200)
assert %{"ammo_groups" => [^ideal_ammo_group]} = json_resp
assert %{"packs" => [^ideal_pack]} = json_resp
assert %{"ammo_types" => [^ideal_ammo_type]} = json_resp
assert %{"containers" => [^ideal_container]} = json_resp
assert %{"shot_groups" => [^ideal_shot_group]} = json_resp

View File

@ -4,7 +4,6 @@ defmodule CanneryWeb.UserAuthTest do
"""
use CanneryWeb.ConnCase, async: true
import CanneryWeb.Gettext
alias Cannery.Accounts
alias CanneryWeb.UserAuth
@ -148,7 +147,7 @@ defmodule CanneryWeb.UserAuthTest do
assert redirected_to(conn) == Routes.user_session_path(conn, :new)
assert get_flash(conn, :error) ==
dgettext("errors", "You must confirm your account and log in to access this page.")
"You must confirm your account and log in to access this page."
end
test "stores the path to redirect to on GET", %{conn: conn} do

View File

@ -4,7 +4,6 @@ defmodule CanneryWeb.UserConfirmationControllerTest do
"""
use CanneryWeb.ConnCase, async: true
import CanneryWeb.Gettext
alias Cannery.{Accounts, Repo}
@moduletag :user_confirmation_controller_test
@ -17,7 +16,7 @@ defmodule CanneryWeb.UserConfirmationControllerTest do
test "renders the confirmation page", %{conn: conn} do
conn = get(conn, Routes.user_confirmation_path(conn, :new))
response = html_response(conn, 200)
assert response =~ dgettext("actions", "Resend confirmation instructions")
assert response =~ "Resend confirmation instructions"
end
end
@ -25,18 +24,12 @@ defmodule CanneryWeb.UserConfirmationControllerTest do
@tag :capture_log
test "sends a new confirmation token", %{conn: conn, user: user} do
conn =
post(conn, Routes.user_confirmation_path(conn, :create), %{
"user" => %{"email" => user.email}
})
post(conn, Routes.user_confirmation_path(conn, :create), %{user: %{email: user.email}})
assert redirected_to(conn) == "/"
assert get_flash(conn, :info) =~
dgettext(
"prompts",
"If your email is in our system and it has not been confirmed yet, " <>
"you will receive an email with instructions shortly."
)
"If your email is in our system and it has not been confirmed yet, you will receive an email with instructions shortly."
assert Repo.get_by!(Accounts.UserToken, user_id: user.id).context == "confirm"
end
@ -45,34 +38,24 @@ defmodule CanneryWeb.UserConfirmationControllerTest do
Repo.update!(Accounts.User.confirm_changeset(user))
conn =
post(conn, Routes.user_confirmation_path(conn, :create), %{
"user" => %{"email" => user.email}
})
post(conn, Routes.user_confirmation_path(conn, :create), %{user: %{email: user.email}})
assert redirected_to(conn) == "/"
assert get_flash(conn, :info) =~
dgettext(
"prompts",
"If your email is in our system and it has not been confirmed yet, " <>
"you will receive an email with instructions shortly."
)
"If your email is in our system and it has not been confirmed yet, you will receive an email with instructions shortly."
end
test "does not send confirmation token if email is invalid", %{conn: conn} do
conn =
post(conn, Routes.user_confirmation_path(conn, :create), %{
"user" => %{"email" => "unknown@example.com"}
user: %{email: "unknown@example.com"}
})
assert redirected_to(conn) == "/"
assert get_flash(conn, :info) =~
dgettext(
"prompts",
"If your email is in our system and it has not been confirmed yet, " <>
"you will receive an email with instructions shortly."
)
"If your email is in our system and it has not been confirmed yet, you will receive an email with instructions shortly."
assert Repo.all(Accounts.UserToken) == []
end
@ -87,10 +70,7 @@ defmodule CanneryWeb.UserConfirmationControllerTest do
conn = get(conn, Routes.user_confirmation_path(conn, :confirm, token))
assert redirected_to(conn) == "/"
assert get_flash(conn, :info) =~
dgettext("prompts", "%{email} confirmed successfully", email: user.email)
assert get_flash(conn, :info) =~ "#{user.email} confirmed successfully"
assert Accounts.get_user!(user.id).confirmed_at
refute get_session(conn, :user_token)
assert Repo.all(Accounts.UserToken) == []
@ -99,8 +79,7 @@ defmodule CanneryWeb.UserConfirmationControllerTest do
conn = get(conn, Routes.user_confirmation_path(conn, :confirm, token))
assert redirected_to(conn) == "/"
assert get_flash(conn, :error) =~
dgettext("errors", "User confirmation link is invalid or it has expired")
assert get_flash(conn, :error) =~ "User confirmation link is invalid or it has expired"
# When logged in
conn =
@ -115,10 +94,7 @@ defmodule CanneryWeb.UserConfirmationControllerTest do
test "does not confirm email with invalid token", %{conn: conn, user: user} do
conn = get(conn, Routes.user_confirmation_path(conn, :confirm, "oops"))
assert redirected_to(conn) == "/"
assert get_flash(conn, :error) =~
dgettext("errors", "User confirmation link is invalid or it has expired")
assert get_flash(conn, :error) =~ "User confirmation link is invalid or it has expired"
refute Accounts.get_user!(user.id).confirmed_at
end
end

View File

@ -4,7 +4,6 @@ defmodule CanneryWeb.UserRegistrationControllerTest do
"""
use CanneryWeb.ConnCase, async: true
import CanneryWeb.Gettext
@moduletag :user_registration_controller_test
@ -12,8 +11,8 @@ defmodule CanneryWeb.UserRegistrationControllerTest do
test "renders registration page", %{conn: conn} do
conn = get(conn, Routes.user_registration_path(conn, :new))
response = html_response(conn, 200)
assert response =~ dgettext("actions", "Register")
assert response =~ dgettext("actions", "Log in")
assert response =~ "Register"
assert response =~ "Log in"
end
test "redirects if already logged in", %{conn: conn} do
@ -29,11 +28,11 @@ defmodule CanneryWeb.UserRegistrationControllerTest do
conn =
post(conn, Routes.user_registration_path(conn, :create), %{
"user" => valid_user_attributes(email: email)
user: valid_user_attributes(email: email)
})
assert get_session(conn, :phoenix_flash) == %{
"info" => dgettext("prompts", "Please check your email to verify your account")
"info" => "Please check your email to verify your account"
}
assert redirected_to(conn) =~ "/"
@ -48,11 +47,11 @@ defmodule CanneryWeb.UserRegistrationControllerTest do
test "render errors for invalid data", %{conn: conn} do
conn =
post(conn, Routes.user_registration_path(conn, :create), %{
"user" => %{"email" => "with spaces", "password" => "too short"}
user: %{email: "with spaces", password: "too short"}
})
response = html_response(conn, 200)
assert response =~ gettext("Register")
assert response =~ "Register"
assert response =~ "must have the @ sign and no spaces"
assert response =~ "should be at least 12 character"
end

View File

@ -4,7 +4,6 @@ defmodule CanneryWeb.UserResetPasswordControllerTest do
"""
use CanneryWeb.ConnCase, async: true
import CanneryWeb.Gettext
alias Cannery.{Accounts, Repo}
@moduletag :user_reset_password_controller_test
@ -17,7 +16,7 @@ defmodule CanneryWeb.UserResetPasswordControllerTest do
test "renders the reset password page", %{conn: conn} do
conn = get(conn, Routes.user_reset_password_path(conn, :new))
response = html_response(conn, 200)
assert response =~ dgettext("actions", "Forgot your password?")
assert response =~ "Forgot your password?"
end
end
@ -25,17 +24,12 @@ defmodule CanneryWeb.UserResetPasswordControllerTest do
@tag :capture_log
test "sends a new reset password token", %{conn: conn, user: user} do
conn =
post(conn, Routes.user_reset_password_path(conn, :create), %{
"user" => %{"email" => user.email}
})
post(conn, Routes.user_reset_password_path(conn, :create), %{user: %{email: user.email}})
assert redirected_to(conn) == "/"
assert get_flash(conn, :info) =~
dgettext(
"prompts",
"If your email is in our system, you will receive instructions to reset your password shortly."
)
"If your email is in our system, you will receive instructions to reset your password shortly."
assert Repo.get_by!(Accounts.UserToken, user_id: user.id).context == "reset_password"
end
@ -43,16 +37,13 @@ defmodule CanneryWeb.UserResetPasswordControllerTest do
test "does not send reset password token if email is invalid", %{conn: conn} do
conn =
post(conn, Routes.user_reset_password_path(conn, :create), %{
"user" => %{"email" => "unknown@example.com"}
user: %{email: "unknown@example.com"}
})
assert redirected_to(conn) == "/"
assert get_flash(conn, :info) =~
dgettext(
"prompts",
"If your email is in our system, you will receive instructions to reset your password shortly."
)
"If your email is in our system, you will receive instructions to reset your password shortly."
assert Repo.all(Accounts.UserToken) == []
end
@ -70,15 +61,13 @@ defmodule CanneryWeb.UserResetPasswordControllerTest do
test "renders reset password", %{conn: conn, token: token} do
conn = get(conn, Routes.user_reset_password_path(conn, :edit, token))
assert html_response(conn, 200) =~ dgettext("actions", "Reset password")
assert html_response(conn, 200) =~ "Reset password"
end
test "does not render reset password with invalid token", %{conn: conn} do
conn = get(conn, Routes.user_reset_password_path(conn, :edit, "oops"))
assert redirected_to(conn) == "/"
assert get_flash(conn, :error) =~
dgettext("errors", "Reset password link is invalid or it has expired")
assert get_flash(conn, :error) =~ "Reset password link is invalid or it has expired"
end
end
@ -95,39 +84,37 @@ defmodule CanneryWeb.UserResetPasswordControllerTest do
test "resets password once", %{conn: conn, user: user, token: token} do
conn =
put(conn, Routes.user_reset_password_path(conn, :update, token), %{
"user" => %{
"password" => "new valid password",
"password_confirmation" => "new valid password"
user: %{
password: "new valid password",
password_confirmation: "new valid password"
}
})
assert redirected_to(conn) == Routes.user_session_path(conn, :new)
refute get_session(conn, :user_token)
assert get_flash(conn, :info) =~ dgettext("prompts", "Password reset successfully")
assert get_flash(conn, :info) =~ "Password reset successfully"
assert Accounts.get_user_by_email_and_password(user.email, "new valid password")
end
test "does not reset password on invalid data", %{conn: conn, token: token} do
conn =
put(conn, Routes.user_reset_password_path(conn, :update, token), %{
"user" => %{
"password" => "too short",
"password_confirmation" => "does not match"
user: %{
password: "too short",
password_confirmation: "does not match"
}
})
response = html_response(conn, 200)
assert response =~ gettext("Reset password")
assert response =~ dgettext("errors", "should be at least 12 character(s)")
assert response =~ dgettext("errors", "does not match password")
assert response =~ "Reset password"
assert response =~ "should be at least 12 character(s)"
assert response =~ "does not match password"
end
test "does not reset password with invalid token", %{conn: conn} do
conn = put(conn, Routes.user_reset_password_path(conn, :update, "oops"))
assert redirected_to(conn) == "/"
assert get_flash(conn, :error) =~
dgettext("errors", "Reset password link is invalid or it has expired")
assert get_flash(conn, :error) =~ "Reset password link is invalid or it has expired"
end
end
end

View File

@ -4,7 +4,6 @@ defmodule CanneryWeb.UserSessionControllerTest do
"""
use CanneryWeb.ConnCase, async: true
import CanneryWeb.Gettext
@moduletag :user_session_controller_test
@ -16,7 +15,7 @@ defmodule CanneryWeb.UserSessionControllerTest do
test "renders log in page", %{conn: conn} do
conn = get(conn, Routes.user_session_path(conn, :new))
response = html_response(conn, 200)
assert response =~ dgettext("actions", "Log in")
assert response =~ "Log in"
end
test "redirects if already logged in", %{conn: conn, current_user: current_user} do
@ -29,7 +28,7 @@ defmodule CanneryWeb.UserSessionControllerTest do
test "logs the user in", %{conn: conn, current_user: current_user} do
conn =
post(conn, Routes.user_session_path(conn, :create), %{
"user" => %{"email" => current_user.email, "password" => valid_user_password()}
user: %{email: current_user.email, password: valid_user_password()}
})
assert get_session(conn, :user_token)
@ -39,16 +38,16 @@ defmodule CanneryWeb.UserSessionControllerTest do
conn = get(conn, "/")
response = html_response(conn, 200)
assert response =~ current_user.email
assert response =~ dgettext("prompts", "Are you sure you want to log out?")
assert response =~ "Are you sure you want to log out?"
end
test "logs the user in with remember me", %{conn: conn, current_user: current_user} do
conn =
post(conn, Routes.user_session_path(conn, :create), %{
"user" => %{
"email" => current_user.email,
"password" => valid_user_password(),
"remember_me" => "true"
user: %{
email: current_user.email,
password: valid_user_password(),
remember_me: "true"
}
})
@ -61,9 +60,9 @@ defmodule CanneryWeb.UserSessionControllerTest do
conn
|> init_test_session(user_return_to: "/foo/bar")
|> post(Routes.user_session_path(conn, :create), %{
"user" => %{
"email" => current_user.email,
"password" => valid_user_password()
user: %{
email: current_user.email,
password: valid_user_password()
}
})
@ -74,12 +73,12 @@ defmodule CanneryWeb.UserSessionControllerTest do
%{conn: conn, current_user: current_user} do
conn =
post(conn, Routes.user_session_path(conn, :create), %{
"user" => %{"email" => current_user.email, "password" => "bad"}
user: %{email: current_user.email, password: "bad"}
})
response = html_response(conn, 200)
assert response =~ dgettext("actions", "Log in")
assert response =~ dgettext("errors", "Invalid email or password")
assert response =~ "Log in"
assert response =~ "Invalid email or password"
end
end
@ -88,14 +87,14 @@ defmodule CanneryWeb.UserSessionControllerTest do
conn = conn |> log_in_user(current_user) |> delete(Routes.user_session_path(conn, :delete))
assert redirected_to(conn) == "/"
refute get_session(conn, :user_token)
assert get_flash(conn, :info) =~ gettext("Logged out successfully")
assert get_flash(conn, :info) =~ "Logged out successfully"
end
test "succeeds even if the user is not logged in", %{conn: conn} do
conn = delete(conn, Routes.user_session_path(conn, :delete))
assert redirected_to(conn) == "/"
refute get_session(conn, :user_token)
assert get_flash(conn, :info) =~ gettext("Logged out successfully")
assert get_flash(conn, :info) =~ "Logged out successfully"
end
end
end

View File

@ -4,7 +4,6 @@ defmodule CanneryWeb.UserSettingsControllerTest do
"""
use CanneryWeb.ConnCase, async: true
import CanneryWeb.Gettext
alias Cannery.Accounts
@moduletag :user_settings_controller_test
@ -15,7 +14,7 @@ defmodule CanneryWeb.UserSettingsControllerTest do
test "renders settings page", %{conn: conn} do
conn = get(conn, Routes.user_settings_path(conn, :edit))
response = html_response(conn, 200)
assert response =~ gettext("Settings")
assert response =~ "Settings"
end
test "redirects if user is not logged in" do
@ -30,40 +29,36 @@ defmodule CanneryWeb.UserSettingsControllerTest do
%{conn: conn, current_user: current_user} do
new_password_conn =
put(conn, Routes.user_settings_path(conn, :update), %{
"action" => "update_password",
"current_password" => valid_user_password(),
"user" => %{
"password" => "new valid password",
"password_confirmation" => "new valid password"
action: "update_password",
current_password: valid_user_password(),
user: %{
password: "new valid password",
password_confirmation: "new valid password"
}
})
assert redirected_to(new_password_conn) == Routes.user_settings_path(conn, :edit)
assert get_session(new_password_conn, :user_token) != get_session(conn, :user_token)
assert get_flash(new_password_conn, :info) =~
dgettext("actions", "Password updated successfully")
assert get_flash(new_password_conn, :info) =~ "Password updated successfully"
assert Accounts.get_user_by_email_and_password(current_user.email, "new valid password")
end
test "does not update password on invalid data", %{conn: conn} do
old_password_conn =
put(conn, Routes.user_settings_path(conn, :update), %{
"action" => "update_password",
"current_password" => "invalid",
"user" => %{
"password" => "too short",
"password_confirmation" => "does not match"
action: "update_password",
current_password: "invalid",
user: %{
password: "too short",
password_confirmation: "does not match"
}
})
response = html_response(old_password_conn, 200)
assert response =~ gettext("Settings")
assert response =~ dgettext("errors", "should be at least 12 character(s)")
assert response =~ dgettext("errors", "does not match password")
assert response =~ dgettext("errors", "is not valid")
assert response =~ "Settings"
assert response =~ "should be at least 12 character(s)"
assert response =~ "does not match password"
assert response =~ "is not valid"
assert get_session(old_password_conn, :user_token) == get_session(conn, :user_token)
end
end
@ -73,18 +68,15 @@ defmodule CanneryWeb.UserSettingsControllerTest do
test "updates the user email", %{conn: conn, current_user: current_user} do
conn =
put(conn, Routes.user_settings_path(conn, :update), %{
"action" => "update_email",
"current_password" => valid_user_password(),
"user" => %{"email" => unique_user_email()}
action: "update_email",
current_password: valid_user_password(),
user: %{email: unique_user_email()}
})
assert redirected_to(conn) == Routes.user_settings_path(conn, :edit)
assert get_flash(conn, :info) =~
dgettext(
"prompts",
"A link to confirm your email change has been sent to the new address."
)
"A link to confirm your email change has been sent to the new address."
assert Accounts.get_user_by_email(current_user.email)
end
@ -92,15 +84,15 @@ defmodule CanneryWeb.UserSettingsControllerTest do
test "does not update email on invalid data", %{conn: conn} do
conn =
put(conn, Routes.user_settings_path(conn, :update), %{
"action" => "update_email",
"current_password" => "invalid",
"user" => %{"email" => "with spaces"}
action: "update_email",
current_password: "invalid",
user: %{email: "with spaces"}
})
response = html_response(conn, 200)
assert response =~ gettext("Settings")
assert response =~ dgettext("errors", "must have the @ sign and no spaces")
assert response =~ dgettext("errors", "is not valid")
assert response =~ "Settings"
assert response =~ "must have the @ sign and no spaces"
assert response =~ "is not valid"
end
end
@ -124,24 +116,19 @@ defmodule CanneryWeb.UserSettingsControllerTest do
%{conn: conn, current_user: current_user, token: token, email: email} do
conn = get(conn, Routes.user_settings_path(conn, :confirm_email, token))
assert redirected_to(conn) == Routes.user_settings_path(conn, :edit)
assert get_flash(conn, :info) =~ dgettext("prompts", "Email changed successfully")
assert get_flash(conn, :info) =~ "Email changed successfully"
refute Accounts.get_user_by_email(current_user.email)
assert Accounts.get_user_by_email(email)
conn = get(conn, Routes.user_settings_path(conn, :confirm_email, token))
assert redirected_to(conn) == Routes.user_settings_path(conn, :edit)
assert get_flash(conn, :error) =~
dgettext("errors", "Email change link is invalid or it has expired")
assert get_flash(conn, :error) =~ "Email change link is invalid or it has expired"
end
test "does not update email with invalid token", %{conn: conn, current_user: current_user} do
conn = get(conn, Routes.user_settings_path(conn, :confirm_email, "oops"))
assert redirected_to(conn) == Routes.user_settings_path(conn, :edit)
assert get_flash(conn, :error) =~
dgettext("errors", "Email change link is invalid or it has expired")
assert get_flash(conn, :error) =~ "Email change link is invalid or it has expired"
assert Accounts.get_user_by_email(current_user.email)
end

View File

@ -1,481 +0,0 @@
defmodule CanneryWeb.AmmoGroupLiveTest do
@moduledoc """
Tests ammo group live pages
"""
use CanneryWeb.ConnCase
import Phoenix.LiveViewTest
import CanneryWeb.Gettext
alias Cannery.{Ammo, Repo}
@moduletag :ammo_group_live_test
@shot_group_create_attrs %{"ammo_left" => 5, "notes" => "some notes"}
@shot_group_update_attrs %{
"count" => 5,
"date" => ~N[2022-02-13 03:17:00],
"notes" => "some updated notes"
}
@create_attrs %{"count" => 42, "notes" => "some notes", "price_paid" => 120.5}
@update_attrs %{"count" => 43, "notes" => "some updated notes", "price_paid" => 456.7}
@ammo_group_create_limit 10_000
@empty_attrs %{
"price_paid" => 50,
"count" => 20
}
@shot_group_attrs %{
"price_paid" => 50,
"count" => 20
}
# @invalid_attrs %{count: -1, notes: nil, price_paid: nil}
defp create_ammo_group(%{current_user: current_user}) do
ammo_type = ammo_type_fixture(current_user)
container = container_fixture(current_user)
{1, [ammo_group]} = ammo_group_fixture(@create_attrs, ammo_type, container, current_user)
%{ammo_type: ammo_type, ammo_group: ammo_group, container: container}
end
defp create_shot_group(%{current_user: current_user, ammo_group: ammo_group}) do
shot_group = shot_group_fixture(@shot_group_update_attrs, current_user, ammo_group)
ammo_group = ammo_group |> Repo.reload!()
%{ammo_group: ammo_group, shot_group: shot_group}
end
defp create_empty_ammo_group(%{
current_user: current_user,
ammo_type: ammo_type,
container: container
}) do
{1, [ammo_group]} = ammo_group_fixture(@empty_attrs, ammo_type, container, current_user)
shot_group = shot_group_fixture(@shot_group_attrs, current_user, ammo_group)
ammo_group = ammo_group |> Repo.reload!()
%{empty_ammo_group: ammo_group, shot_group: shot_group}
end
describe "Index of ammo group" do
setup [:register_and_log_in_user, :create_ammo_group]
test "lists all 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 =~ gettext("Ammo")
assert html =~ ammo_group.ammo_type.name
end
test "can sort by type",
%{conn: conn, container: container, current_user: current_user} do
rifle_type = ammo_type_fixture(%{"type" => "rifle"}, current_user)
{1, [rifle_ammo_group]} = ammo_group_fixture(rifle_type, container, current_user)
shotgun_type = ammo_type_fixture(%{"type" => "shotgun"}, current_user)
{1, [shotgun_ammo_group]} = ammo_group_fixture(shotgun_type, container, current_user)
pistol_type = ammo_type_fixture(%{"type" => "pistol"}, current_user)
{1, [pistol_ammo_group]} = ammo_group_fixture(pistol_type, container, current_user)
{:ok, index_live, html} = live(conn, Routes.ammo_group_index_path(conn, :index))
assert html =~ "All"
assert html =~ rifle_ammo_group.ammo_type.name
assert html =~ shotgun_ammo_group.ammo_type.name
assert html =~ pistol_ammo_group.ammo_type.name
html =
index_live
|> form(~s/form[phx-change="change_type"]/)
|> render_change(ammo_type: %{type: :rifle})
assert html =~ rifle_ammo_group.ammo_type.name
refute html =~ shotgun_ammo_group.ammo_type.name
refute html =~ pistol_ammo_group.ammo_type.name
html =
index_live
|> form(~s/form[phx-change="change_type"]/)
|> render_change(ammo_type: %{type: :shotgun})
refute html =~ rifle_ammo_group.ammo_type.name
assert html =~ shotgun_ammo_group.ammo_type.name
refute html =~ pistol_ammo_group.ammo_type.name
html =
index_live
|> form(~s/form[phx-change="change_type"]/)
|> render_change(ammo_type: %{type: :pistol})
refute html =~ rifle_ammo_group.ammo_type.name
refute html =~ shotgun_ammo_group.ammo_type.name
assert html =~ pistol_ammo_group.ammo_type.name
html =
index_live
|> form(~s/form[phx-change="change_type"]/)
|> render_change(ammo_type: %{type: :all})
assert html =~ rifle_ammo_group.ammo_type.name
assert html =~ shotgun_ammo_group.ammo_type.name
assert html =~ pistol_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(~s/form[phx-change="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(~s/form[phx-change="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(~s/form[phx-change="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))
assert index_live |> element("a", dgettext("actions", "Add Ammo")) |> render_click() =~
dgettext("actions", "Add Ammo")
assert_patch(index_live, Routes.ammo_group_index_path(conn, :new))
# assert index_live
# |> form("#ammo_group-form", ammo_group: @invalid_attrs)
# |> render_change() =~ dgettext("errors", "can't be blank")
{:ok, _view, html} =
index_live
|> form("#ammo_group-form", ammo_group: @create_attrs)
|> render_submit()
|> follow_redirect(conn, Routes.ammo_group_index_path(conn, :index))
assert html =~ dgettext("prompts", "Ammo added successfully")
assert html =~ "\n42\n"
end
test "saves multiple new ammo_groups", %{conn: conn, current_user: current_user} do
multiplier = 25
{:ok, index_live, _html} = live(conn, Routes.ammo_group_index_path(conn, :index))
assert index_live |> element("a", dgettext("actions", "Add Ammo")) |> render_click() =~
dgettext("actions", "Add Ammo")
assert_patch(index_live, Routes.ammo_group_index_path(conn, :new))
# assert index_live
# |> form("#ammo_group-form", ammo_group: @invalid_attrs)
# |> render_change() =~ dgettext("errors", "can't be blank")
{:ok, _view, html} =
index_live
|> form("#ammo_group-form",
ammo_group: @create_attrs |> Map.put("multiplier", to_string(multiplier))
)
|> render_submit()
|> follow_redirect(conn, Routes.ammo_group_index_path(conn, :index))
assert html =~ dgettext("prompts", "Ammo added successfully")
assert Ammo.list_ammo_groups(nil, :all, current_user) |> Enum.count() == multiplier + 1
end
test "does not save invalid number of new ammo_groups", %{conn: conn} do
{:ok, index_live, _html} = live(conn, Routes.ammo_group_index_path(conn, :index))
assert index_live |> element("a", dgettext("actions", "Add Ammo")) |> render_click() =~
dgettext("actions", "Add Ammo")
assert_patch(index_live, Routes.ammo_group_index_path(conn, :new))
# assert index_live
# |> form("#ammo_group-form", ammo_group: @invalid_attrs)
# |> render_change() =~ dgettext("errors", "can't be blank")
assert index_live
|> form("#ammo_group-form", ammo_group: @create_attrs |> Map.put("multiplier", "0"))
|> render_submit() =~
dgettext(
"errors",
"Invalid number of copies, must be between 1 and %{max}. Was %{multiplier}",
multiplier: 0,
max: @ammo_group_create_limit
)
assert index_live
|> form("#ammo_group-form",
ammo_group:
@create_attrs |> Map.put("multiplier", to_string(@ammo_group_create_limit + 1))
)
|> render_submit() =~
dgettext(
"errors",
"Invalid number of copies, must be between 1 and %{max}. Was %{multiplier}",
multiplier: @ammo_group_create_limit + 1,
max: @ammo_group_create_limit
)
end
test "updates ammo_group in listing", %{conn: conn, ammo_group: ammo_group} do
{:ok, index_live, _html} = live(conn, Routes.ammo_group_index_path(conn, :index))
assert index_live
|> element(~s/a[aria-label="Edit ammo group of #{ammo_group.count} bullets"]/)
|> render_click() =~
gettext("Edit ammo")
assert_patch(index_live, Routes.ammo_group_index_path(conn, :edit, ammo_group))
# assert index_live
# |> form("#ammo_group-form", ammo_group: @invalid_attrs)
# |> render_change() =~ dgettext("errors", "can't be blank")
{:ok, _view, html} =
index_live
|> form("#ammo_group-form", ammo_group: @update_attrs)
|> render_submit()
|> follow_redirect(conn, Routes.ammo_group_index_path(conn, :index))
assert html =~ dgettext("prompts", "Ammo updated successfully")
assert html =~ "\n43\n"
end
test "clones ammo_group in listing", %{conn: conn, ammo_group: ammo_group} do
{:ok, index_live, _html} = live(conn, Routes.ammo_group_index_path(conn, :index))
html =
index_live
|> element(~s/a[aria-label="Clone ammo group of #{ammo_group.count} bullets"]/)
|> render_click()
assert html =~ dgettext("actions", "Add Ammo")
assert html =~ gettext("$%{amount}", amount: display_currency(120.5))
assert_patch(index_live, Routes.ammo_group_index_path(conn, :clone, ammo_group))
# assert index_live
# |> form("#ammo_group-form", ammo_group: @invalid_attrs)
# |> render_change() =~ dgettext("errors", "can't be blank")
{:ok, _view, html} =
index_live
|> form("#ammo_group-form")
|> render_submit()
|> follow_redirect(conn, Routes.ammo_group_index_path(conn, :index))
assert html =~ dgettext("prompts", "Ammo added successfully")
assert html =~ "\n42\n"
assert html =~ gettext("$%{amount}", amount: display_currency(120.5))
end
test "clones ammo_group in listing with updates", %{conn: conn, ammo_group: ammo_group} do
{:ok, index_live, _html} = live(conn, Routes.ammo_group_index_path(conn, :index))
html =
index_live
|> element(~s/a[aria-label="Clone ammo group of #{ammo_group.count} bullets"]/)
|> render_click()
assert html =~ dgettext("actions", "Add Ammo")
assert html =~ gettext("$%{amount}", amount: display_currency(120.5))
assert_patch(index_live, Routes.ammo_group_index_path(conn, :clone, ammo_group))
# assert index_live
# |> form("#ammo_group-form", ammo_group: @invalid_attrs)
# |> render_change() =~ dgettext("errors", "can't be blank")
{:ok, _view, html} =
index_live
|> form("#ammo_group-form", ammo_group: Map.merge(@create_attrs, %{"count" => 43}))
|> render_submit()
|> follow_redirect(conn, Routes.ammo_group_index_path(conn, :index))
assert html =~ dgettext("prompts", "Ammo added successfully")
assert html =~ "\n43\n"
assert html =~ gettext("$%{amount}", amount: display_currency(120.5))
end
test "deletes ammo_group in listing", %{conn: conn, ammo_group: ammo_group} do
{:ok, index_live, _html} = live(conn, Routes.ammo_group_index_path(conn, :index))
assert index_live
|> element(~s/a[aria-label="Delete ammo group of #{ammo_group.count} bullets"]/)
|> render_click()
refute has_element?(index_live, "#ammo_group-#{ammo_group.id}")
end
test "saves new shot_group", %{conn: conn, ammo_group: ammo_group} do
{:ok, index_live, _html} = live(conn, Routes.ammo_group_index_path(conn, :index))
assert index_live |> element("a", dgettext("actions", "Record shots")) |> render_click() =~
gettext("Record shots")
assert_patch(index_live, Routes.ammo_group_index_path(conn, :add_shot_group, ammo_group))
# assert index_live
# |> form("#shot_group-form", shot_group: @invalid_attrs)
# |> render_change() =~ dgettext("errors", "is invalid")
{:ok, _view, html} =
index_live
|> form("#shot-group-form", shot_group: @shot_group_create_attrs)
|> render_submit()
|> follow_redirect(conn, Routes.ammo_group_index_path(conn, :index))
assert html =~ dgettext("prompts", "Shots recorded successfully")
end
@spec display_currency(float()) :: String.t()
defp display_currency(float), do: :erlang.float_to_binary(float, decimals: 2)
end
describe "Index of empty ammo group" do
setup [:register_and_log_in_user, :create_ammo_group, :create_empty_ammo_group]
test "hides empty ammo groups by default", %{
conn: conn,
empty_ammo_group: ammo_group,
current_user: current_user
} do
{:ok, show_live, html} = live(conn, Routes.ammo_group_index_path(conn, :index))
assert html =~ dgettext("actions", "Show used")
refute html =~ gettext("$%{amount}", amount: display_currency(50.00))
percentage = ammo_group |> Ammo.get_percentage_remaining(current_user)
refute html =~ "\n#{gettext("%{percentage}%", percentage: percentage)}\n"
html =
show_live
|> element(~s/input[type="checkbox"][aria-labelledby="toggle_show_used-label"}]/)
|> render_click()
assert html =~ gettext("$%{amount}", amount: display_currency(50.00))
percentage = ammo_group |> Ammo.get_percentage_remaining(current_user)
assert html =~ "\n#{gettext("%{percentage}%", percentage: percentage)}\n"
end
end
describe "Show ammo group" do
setup [:register_and_log_in_user, :create_ammo_group]
test "displays ammo_group", %{conn: conn, ammo_group: ammo_group} do
{:ok, _show_live, html} = live(conn, Routes.ammo_group_show_path(conn, :show, ammo_group))
ammo_group = ammo_group |> Repo.preload(:ammo_type)
assert html =~ gettext("Show Ammo")
assert html =~ ammo_group.ammo_type.name
end
test "updates ammo_group within modal", %{conn: conn, ammo_group: ammo_group} do
{:ok, show_live, _html} = live(conn, Routes.ammo_group_show_path(conn, :show, ammo_group))
assert show_live
|> element(~s/a[aria-label="Edit ammo group of #{ammo_group.count} bullets"]/)
|> render_click() =~
gettext("Edit Ammo")
assert_patch(show_live, Routes.ammo_group_show_path(conn, :edit, ammo_group))
# assert show_live
# |> form("#ammo_group-form", ammo_group: @invalid_attrs)
# |> render_change() =~ dgettext("errors", "can't be blank")
{:ok, _view, html} =
show_live
|> form("#ammo_group-form", ammo_group: @update_attrs)
|> render_submit()
|> follow_redirect(conn, Routes.ammo_group_show_path(conn, :show, ammo_group))
assert html =~ dgettext("prompts", "Ammo updated successfully")
assert html =~ "some updated notes"
end
test "saves new shot_group", %{conn: conn, ammo_group: ammo_group} do
{:ok, index_live, _html} = live(conn, Routes.ammo_group_show_path(conn, :show, ammo_group))
assert index_live |> element("a", dgettext("actions", "Record shots")) |> render_click() =~
gettext("Record shots")
assert_patch(index_live, Routes.ammo_group_show_path(conn, :add_shot_group, ammo_group))
# assert index_live
# |> form("#shot_group-form", shot_group: @invalid_attrs)
# |> render_change() =~ dgettext("errors", "is invalid")
{:ok, _view, html} =
index_live
|> form("#shot-group-form", shot_group: @shot_group_create_attrs)
|> render_submit()
|> follow_redirect(conn, Routes.ammo_group_show_path(conn, :show, ammo_group))
assert html =~ dgettext("prompts", "Shots recorded successfully")
end
end
describe "Show ammo group with shot group" do
setup [:register_and_log_in_user, :create_ammo_group, :create_shot_group]
test "updates shot_group in listing",
%{conn: conn, ammo_group: ammo_group, shot_group: shot_group} do
{:ok, index_live, _html} = live(conn, Routes.ammo_group_show_path(conn, :edit, ammo_group))
assert index_live
|> element(~s/a[aria-label="Edit shot group of #{shot_group.count} shots"]/)
|> render_click() =~
gettext("Edit Shot Records")
assert_patch(
index_live,
Routes.ammo_group_show_path(conn, :edit_shot_group, ammo_group, shot_group)
)
# assert index_live
# |> form("#shot_group-form", shot_group: @invalid_attrs)
# |> render_change() =~ dgettext("errors", "is invalid")
{:ok, _view, html} =
index_live
|> form("#shot-group-form", shot_group: @shot_group_update_attrs)
|> render_submit()
|> follow_redirect(conn, Routes.ammo_group_show_path(conn, :show, ammo_group))
assert html =~ dgettext("actions", "Shot records updated successfully")
assert html =~ "some updated notes"
end
test "deletes shot_group in listing",
%{conn: conn, ammo_group: ammo_group, shot_group: shot_group} do
{:ok, index_live, _html} =
live(conn, Routes.ammo_group_show_path(conn, :edit_shot_group, ammo_group, shot_group))
assert index_live
|> element(~s/a[aria-label="Delete shot record of #{shot_group.count} shots"]/)
|> render_click()
refute has_element?(index_live, "#shot_group-#{shot_group.id}")
end
end
end

View File

@ -5,63 +5,59 @@ defmodule CanneryWeb.AmmoTypeLiveTest do
use CanneryWeb.ConnCase
import Phoenix.LiveViewTest
import CanneryWeb.Gettext
alias Cannery.{Ammo, Repo}
@moduletag :ammo_type_live_test
@create_attrs %{
"bullet_type" => "some bullet_type",
"case_material" => "some case_material",
"desc" => "some desc",
"manufacturer" => "some manufacturer",
"name" => "some name",
"grains" => 120
bullet_type: "some bullet_type",
case_material: "some case_material",
desc: "some desc",
manufacturer: "some manufacturer",
name: "some name",
grains: 120
}
@update_attrs %{
"bullet_type" => "some updated bullet_type",
"case_material" => "some updated case_material",
"desc" => "some updated desc",
"manufacturer" => "some updated manufacturer",
"name" => "some updated name",
"grains" => 456
bullet_type: "some updated bullet_type",
case_material: "some updated case_material",
desc: "some updated desc",
manufacturer: "some updated manufacturer",
name: "some updated name",
grains: 456
}
@ammo_group_attrs %{
"notes" => "some ammo group",
"count" => 20
@invalid_attrs %{
bullet_type: nil,
case_material: nil,
desc: nil,
manufacturer: nil,
name: nil,
grains: nil
}
@pack_attrs %{
notes: "some pack",
count: 20
}
@shot_group_attrs %{
"notes" => "some shot group",
"count" => 20
notes: "some shot group",
count: 20
}
# @invalid_attrs %{
# "bullet_type" => nil,
# "case_material" => nil,
# "desc" => nil,
# "manufacturer" => nil,
# "name" => nil,
# "grains" => nil
# }
defp create_ammo_type(%{current_user: current_user}) do
%{ammo_type: ammo_type_fixture(@create_attrs, current_user)}
[ammo_type: ammo_type_fixture(@create_attrs, current_user)]
end
defp create_ammo_group(%{ammo_type: ammo_type, current_user: current_user}) do
defp create_pack(%{ammo_type: ammo_type, current_user: current_user}) do
container = container_fixture(current_user)
{1, [ammo_group]} = ammo_group_fixture(@ammo_group_attrs, ammo_type, container, current_user)
%{ammo_group: ammo_group, container: container}
{1, [pack]} = pack_fixture(@pack_attrs, ammo_type, container, current_user)
[pack: pack, container: container]
end
defp create_empty_ammo_group(%{ammo_type: ammo_type, current_user: current_user}) do
defp create_empty_pack(%{ammo_type: ammo_type, current_user: current_user}) do
container = container_fixture(current_user)
{1, [ammo_group]} = ammo_group_fixture(@ammo_group_attrs, ammo_type, container, current_user)
shot_group = shot_group_fixture(@shot_group_attrs, current_user, ammo_group)
ammo_group = ammo_group |> Repo.reload!()
%{ammo_group: ammo_group, container: container, shot_group: shot_group}
{1, [pack]} = pack_fixture(@pack_attrs, ammo_type, container, current_user)
shot_group = shot_group_fixture(@shot_group_attrs, current_user, pack)
pack = pack |> Repo.reload!()
[pack: pack, container: container, shot_group: shot_group]
end
describe "Index" do
@ -69,15 +65,14 @@ defmodule CanneryWeb.AmmoTypeLiveTest do
test "lists all ammo_types", %{conn: conn, ammo_type: ammo_type} do
{:ok, _index_live, html} = live(conn, Routes.ammo_type_index_path(conn, :index))
assert html =~ gettext("Catalog")
assert html =~ "Catalog"
assert html =~ ammo_type.bullet_type
end
test "can sort by type", %{conn: conn, current_user: current_user} do
rifle_type = ammo_type_fixture(%{"type" => "rifle"}, current_user)
shotgun_type = ammo_type_fixture(%{"type" => "shotgun"}, current_user)
pistol_type = ammo_type_fixture(%{"type" => "pistol"}, current_user)
test "can sort by class", %{conn: conn, current_user: current_user} do
rifle_type = ammo_type_fixture(%{class: :rifle}, current_user)
shotgun_type = ammo_type_fixture(%{class: :shotgun}, current_user)
pistol_type = ammo_type_fixture(%{class: :pistol}, current_user)
{:ok, index_live, html} = live(conn, Routes.ammo_type_index_path(conn, :index))
@ -89,8 +84,8 @@ defmodule CanneryWeb.AmmoTypeLiveTest do
html =
index_live
|> form(~s/form[phx-change="change_type"]/)
|> render_change(ammo_type: %{type: :rifle})
|> form(~s/form[phx-change="change_class"]/)
|> render_change(ammo_type: %{class: :rifle})
assert html =~ rifle_type.name
refute html =~ shotgun_type.name
@ -98,8 +93,8 @@ defmodule CanneryWeb.AmmoTypeLiveTest do
html =
index_live
|> form(~s/form[phx-change="change_type"]/)
|> render_change(ammo_type: %{type: :shotgun})
|> form(~s/form[phx-change="change_class"]/)
|> render_change(ammo_type: %{class: :shotgun})
refute html =~ rifle_type.name
assert html =~ shotgun_type.name
@ -107,8 +102,8 @@ defmodule CanneryWeb.AmmoTypeLiveTest do
html =
index_live
|> form(~s/form[phx-change="change_type"]/)
|> render_change(ammo_type: %{type: :pistol})
|> form(~s/form[phx-change="change_class"]/)
|> render_change(ammo_type: %{class: :pistol})
refute html =~ rifle_type.name
refute html =~ shotgun_type.name
@ -116,8 +111,8 @@ defmodule CanneryWeb.AmmoTypeLiveTest do
html =
index_live
|> form(~s/form[phx-change="change_type"]/)
|> render_change(ammo_type: %{type: :all})
|> form(~s/form[phx-change="change_class"]/)
|> render_change(ammo_type: %{class: :all})
assert html =~ rifle_type.name
assert html =~ shotgun_type.name
@ -152,14 +147,12 @@ defmodule CanneryWeb.AmmoTypeLiveTest do
test "saves new ammo_type", %{conn: conn, current_user: current_user, ammo_type: ammo_type} do
{:ok, index_live, _html} = live(conn, Routes.ammo_type_index_path(conn, :index))
assert index_live |> element("a", dgettext("actions", "New Ammo type")) |> render_click() =~
gettext("New Ammo type")
assert index_live |> element("a", "New Ammo type") |> render_click() =~ "New Ammo type"
assert_patch(index_live, Routes.ammo_type_index_path(conn, :new))
# assert index_live
# |> form("#ammo_type-form", ammo_type: @invalid_attrs)
# |> render_change() =~ dgettext("errors", "can't be blank")
assert index_live
|> form("#ammo_type-form")
|> render_change(ammo_type: @invalid_attrs) =~ "can&#39;t be blank"
{:ok, _view, html} =
index_live
@ -168,7 +161,7 @@ defmodule CanneryWeb.AmmoTypeLiveTest do
|> follow_redirect(conn, Routes.ammo_type_index_path(conn, :index))
ammo_type = ammo_type.id |> Ammo.get_ammo_type!(current_user)
assert html =~ dgettext("prompts", "%{name} created successfully", name: ammo_type.name)
assert html =~ "#{ammo_type.name} created successfully"
assert html =~ "some bullet_type"
end
@ -177,13 +170,13 @@ defmodule CanneryWeb.AmmoTypeLiveTest do
{:ok, index_live, _html} = live(conn, Routes.ammo_type_index_path(conn, :index))
assert index_live |> element(~s/a[aria-label="Edit #{ammo_type.name}"]/) |> render_click() =~
gettext("Edit %{ammo_type_name}", ammo_type_name: ammo_type.name)
"Edit #{ammo_type.name}"
assert_patch(index_live, Routes.ammo_type_index_path(conn, :edit, ammo_type))
# assert index_live
# |> form("#ammo_type-form", ammo_type: @invalid_attrs)
# |> render_change() =~ dgettext("errors", "can't be blank")
assert index_live
|> form("#ammo_type-form")
|> render_change(ammo_type: @invalid_attrs) =~ "can&#39;t be blank"
{:ok, _view, html} =
index_live
@ -192,7 +185,7 @@ defmodule CanneryWeb.AmmoTypeLiveTest do
|> follow_redirect(conn, Routes.ammo_type_index_path(conn, :index))
ammo_type = ammo_type.id |> Ammo.get_ammo_type!(current_user)
assert html =~ dgettext("prompts", "%{name} updated successfully", name: ammo_type.name)
assert html =~ "#{ammo_type.name} updated successfully"
assert html =~ "some updated bullet_type"
end
@ -201,14 +194,14 @@ defmodule CanneryWeb.AmmoTypeLiveTest do
{:ok, index_live, _html} = live(conn, Routes.ammo_type_index_path(conn, :index))
html = index_live |> element(~s/a[aria-label="Clone #{ammo_type.name}"]/) |> render_click()
assert html =~ gettext("New Ammo type")
assert html =~ "New Ammo type"
assert html =~ "some bullet_type"
assert_patch(index_live, Routes.ammo_type_index_path(conn, :clone, ammo_type))
# assert index_live
# |> form("#ammo_type-form", ammo_type: @invalid_attrs)
# |> render_change() =~ dgettext("errors", "can't be blank")
assert index_live
|> form("#ammo_type-form")
|> render_change(ammo_type: @invalid_attrs) =~ "can&#39;t be blank"
{:ok, _view, html} =
index_live
@ -217,7 +210,7 @@ defmodule CanneryWeb.AmmoTypeLiveTest do
|> follow_redirect(conn, Routes.ammo_type_index_path(conn, :index))
ammo_type = ammo_type.id |> Ammo.get_ammo_type!(current_user)
assert html =~ dgettext("prompts", "%{name} created successfully", name: ammo_type.name)
assert html =~ "#{ammo_type.name} created successfully"
assert html =~ "some bullet_type"
end
@ -226,64 +219,63 @@ defmodule CanneryWeb.AmmoTypeLiveTest do
{:ok, index_live, _html} = live(conn, Routes.ammo_type_index_path(conn, :index))
html = index_live |> element(~s/a[aria-label="Clone #{ammo_type.name}"]/) |> render_click()
assert html =~ gettext("New Ammo type")
assert html =~ "New Ammo type"
assert html =~ "some bullet_type"
assert_patch(index_live, Routes.ammo_type_index_path(conn, :clone, ammo_type))
# assert index_live
# |> form("#ammo_type-form", ammo_type: @invalid_attrs)
# |> render_change() =~ dgettext("errors", "can't be blank")
assert index_live
|> form("#ammo_type-form")
|> render_change(ammo_type: @invalid_attrs) =~ "can&#39;t be blank"
{:ok, _view, html} =
index_live
|> form("#ammo_type-form")
|> render_submit(
ammo_type: Map.merge(@create_attrs, %{"bullet_type" => "some updated bullet_type"})
ammo_type: Map.merge(@create_attrs, %{bullet_type: "some updated bullet_type"})
)
|> follow_redirect(conn, Routes.ammo_type_index_path(conn, :index))
ammo_type = ammo_type.id |> Ammo.get_ammo_type!(current_user)
assert html =~ dgettext("prompts", "%{name} created successfully", name: ammo_type.name)
assert html =~ "#{ammo_type.name} created successfully"
assert html =~ "some updated bullet_type"
end
test "deletes ammo_type in listing", %{conn: conn, ammo_type: ammo_type} do
{:ok, index_live, _html} = live(conn, Routes.ammo_type_index_path(conn, :index))
assert index_live |> element(~s/a[aria-label="Delete #{ammo_type.name}"]/) |> render_click()
refute has_element?(index_live, "#ammo_type-#{ammo_type.id}")
end
end
describe "Index with ammo group" do
setup [:register_and_log_in_user, :create_ammo_type, :create_ammo_group]
describe "Index with pack" do
setup [:register_and_log_in_user, :create_ammo_type, :create_pack]
test "shows used ammo groups on toggle",
%{conn: conn, ammo_group: ammo_group, current_user: current_user} do
test "shows used packs on toggle",
%{conn: conn, pack: pack, current_user: current_user} do
{:ok, index_live, html} = live(conn, Routes.ammo_type_index_path(conn, :index))
assert html =~ dgettext("actions", "Show used")
refute html =~ gettext("Used rounds")
refute html =~ gettext("Total ever rounds")
refute html =~ gettext("Used packs")
refute html =~ gettext("Total ever packs")
assert html =~ "Show used"
refute html =~ "Used rounds"
refute html =~ "Total ever rounds"
refute html =~ "Used packs"
refute html =~ "Total ever packs"
html =
index_live
|> element(~s/input[type="checkbox"][aria-labelledby="toggle_show_used-label"}]/)
|> render_click()
assert html =~ gettext("Used rounds")
assert html =~ gettext("Total ever rounds")
assert html =~ gettext("Used packs")
assert html =~ gettext("Total ever packs")
assert html =~ "Used rounds"
assert html =~ "Total ever rounds"
assert html =~ "Used packs"
assert html =~ "Total ever packs"
assert html =~ "\n20\n"
assert html =~ "\n0\n"
assert html =~ "\n1\n"
shot_group_fixture(%{"count" => 5}, current_user, ammo_group)
shot_group_fixture(%{count: 5}, current_user, pack)
{:ok, index_live, _html} = live(conn, Routes.ammo_type_index_path(conn, :index))
@ -315,13 +307,13 @@ defmodule CanneryWeb.AmmoTypeLiveTest do
{:ok, show_live, _html} = live(conn, Routes.ammo_type_show_path(conn, :show, ammo_type))
assert show_live |> element(~s/a[aria-label="Edit #{ammo_type.name}"]/) |> render_click() =~
gettext("Edit %{ammo_type_name}", ammo_type_name: name)
"Edit #{name}"
assert_patch(show_live, Routes.ammo_type_show_path(conn, :edit, ammo_type))
# assert show_live
# |> form("#ammo_type-form", ammo_type: @invalid_attrs)
# |> render_change() =~ dgettext("errors", "can't be blank")
assert show_live
|> form("#ammo_type-form")
|> render_change(ammo_type: @invalid_attrs) =~ "can&#39;t be blank"
{:ok, _view, html} =
show_live
@ -330,15 +322,15 @@ defmodule CanneryWeb.AmmoTypeLiveTest do
|> follow_redirect(conn, Routes.ammo_type_show_path(conn, :show, ammo_type))
ammo_type = ammo_type.id |> Ammo.get_ammo_type!(current_user)
assert html =~ dgettext("prompts", "%{name} updated successfully", name: ammo_type.name)
assert html =~ "#{ammo_type.name} updated successfully"
assert html =~ "some updated bullet_type"
end
end
describe "Show ammo type with ammo group" do
setup [:register_and_log_in_user, :create_ammo_type, :create_ammo_group]
describe "Show ammo type with pack" do
setup [:register_and_log_in_user, :create_ammo_type, :create_pack]
test "displays ammo group", %{
test "displays pack", %{
conn: conn,
ammo_type: %{name: ammo_type_name} = ammo_type,
container: %{name: container_name}
@ -350,7 +342,7 @@ defmodule CanneryWeb.AmmoTypeLiveTest do
assert html =~ container_name
end
test "displays ammo group in table",
test "displays pack in table",
%{conn: conn, ammo_type: ammo_type, container: %{name: container_name}} do
{:ok, show_live, _html} = live(conn, Routes.ammo_type_show_path(conn, :show, ammo_type))
@ -364,14 +356,13 @@ defmodule CanneryWeb.AmmoTypeLiveTest do
end
end
describe "Show ammo type with empty ammo group" do
setup [:register_and_log_in_user, :create_ammo_type, :create_empty_ammo_group]
describe "Show ammo type with empty pack" do
setup [:register_and_log_in_user, :create_ammo_type, :create_empty_pack]
test "displays empty ammo groups on toggle",
test "displays empty packs on toggle",
%{conn: conn, ammo_type: ammo_type, container: %{name: container_name}} do
{:ok, show_live, html} = live(conn, Routes.ammo_type_show_path(conn, :show, ammo_type))
assert html =~ dgettext("actions", "Show used")
assert html =~ "Show used"
refute html =~ "\n20\n"
html =
@ -384,7 +375,7 @@ defmodule CanneryWeb.AmmoTypeLiveTest do
assert html =~ container_name
end
test "displays empty ammo groups in table on toggle",
test "displays empty packs in table on toggle",
%{conn: conn, ammo_type: ammo_type, container: %{name: container_name}} do
{:ok, show_live, _html} = live(conn, Routes.ammo_type_show_path(conn, :show, ammo_type))
@ -393,7 +384,7 @@ defmodule CanneryWeb.AmmoTypeLiveTest do
|> element(~s/input[type="checkbox"][aria-labelledby="toggle_table-label"}]/)
|> render_click()
assert html =~ dgettext("actions", "Show used")
assert html =~ "Show used"
refute html =~ "\n20\n"
html =

View File

@ -5,48 +5,46 @@ defmodule CanneryWeb.ContainerLiveTest do
use CanneryWeb.ConnCase
import Phoenix.LiveViewTest
import CanneryWeb.Gettext
alias Cannery.Containers
@moduletag :container_live_test
@create_attrs %{
"desc" => "some desc",
"location" => "some location",
"name" => "some name",
"type" => "some type"
desc: "some desc",
location: "some location",
name: "some name",
type: "some type"
}
@update_attrs %{
"desc" => "some updated desc",
"location" => "some updated location",
"name" => "some updated name",
"type" => "some updated type"
desc: "some updated desc",
location: "some updated location",
name: "some updated name",
type: "some updated type"
}
@invalid_attrs %{desc: nil, location: nil, name: nil, type: nil}
@ammo_type_attrs %{
"bullet_type" => "some bullet_type",
"case_material" => "some case_material",
"desc" => "some desc",
"manufacturer" => "some manufacturer",
"name" => "some name",
"grains" => 120
bullet_type: "some bullet_type",
case_material: "some case_material",
desc: "some desc",
manufacturer: "some manufacturer",
name: "some name",
grains: 120
}
@ammo_group_attrs %{
"notes" => "some ammo group",
"count" => 20
@pack_attrs %{
notes: "some pack",
count: 20
}
# @invalid_attrs %{desc: nil, location: nil, name: nil, type: nil}
defp create_container(%{current_user: current_user}) do
container = container_fixture(@create_attrs, current_user)
%{container: container}
[container: container]
end
defp create_ammo_group(%{container: container, current_user: current_user}) do
defp create_pack(%{container: container, current_user: current_user}) do
ammo_type = ammo_type_fixture(@ammo_type_attrs, current_user)
{1, [ammo_group]} = ammo_group_fixture(@ammo_group_attrs, ammo_type, container, current_user)
{1, [pack]} = pack_fixture(@pack_attrs, ammo_type, container, current_user)
%{ammo_type: ammo_type, ammo_group: ammo_group}
[ammo_type: ammo_type, pack: pack]
end
describe "Index" do
@ -55,7 +53,7 @@ defmodule CanneryWeb.ContainerLiveTest do
test "lists all containers", %{conn: conn, container: container} do
{:ok, _index_live, html} = live(conn, Routes.container_index_path(conn, :index))
assert html =~ gettext("Containers")
assert html =~ "Containers"
assert html =~ container.location
end
@ -67,7 +65,7 @@ defmodule CanneryWeb.ContainerLiveTest do
|> element(~s/input[type="checkbox"][aria-labelledby="toggle_table-label"}]/)
|> render_click()
assert html =~ gettext("Containers")
assert html =~ "Containers"
assert html =~ container.location
end
@ -77,22 +75,20 @@ defmodule CanneryWeb.ContainerLiveTest do
assert html =~ container.location
assert index_live
|> form(~s/form[phx-change="search"]/,
search: %{search_term: container.location}
)
|> render_change() =~ container.location
|> form(~s/form[phx-change="search"]/)
|> render_change(search: %{search_term: container.location}) =~ container.location
assert_patch(index_live, Routes.container_index_path(conn, :search, container.location))
refute index_live
|> form(~s/form[phx-change="search"]/, search: %{search_term: "something_else"})
|> render_change() =~ container.location
|> form(~s/form[phx-change="search"]/)
|> render_change(search: %{search_term: "something_else"}) =~ container.location
assert_patch(index_live, Routes.container_index_path(conn, :search, "something_else"))
assert index_live
|> form(~s/form[phx-change="search"]/, search: %{search_term: ""})
|> render_change() =~ container.location
|> form(~s/form[phx-change="search"]/)
|> render_change(search: %{search_term: ""}) =~ container.location
assert_patch(index_live, Routes.container_index_path(conn, :index))
end
@ -100,22 +96,20 @@ defmodule CanneryWeb.ContainerLiveTest do
test "saves new container", %{conn: conn, container: container} do
{:ok, index_live, _html} = live(conn, Routes.container_index_path(conn, :index))
assert index_live |> element("a", dgettext("actions", "New Container")) |> render_click() =~
gettext("New Container")
assert index_live |> element("a", "New Container") |> render_click() =~ "New Container"
assert_patch(index_live, Routes.container_index_path(conn, :new))
# assert index_live
# |> form("#container-form", container: @invalid_attrs)
# |> render_change() =~ dgettext("errors", "can't be blank")
assert index_live
|> form("#container-form")
|> render_change(container: @invalid_attrs) =~ "can&#39;t be blank"
{:ok, _view, html} =
index_live
|> form("#container-form", container: @create_attrs)
|> render_submit()
|> form("#container-form")
|> render_submit(container: @create_attrs)
|> follow_redirect(conn, Routes.container_index_path(conn, :index))
assert html =~ dgettext("prompts", "%{name} created successfully", name: container.name)
assert html =~ "#{container.name} created successfully"
assert html =~ "some location"
end
@ -127,22 +121,22 @@ defmodule CanneryWeb.ContainerLiveTest do
{:ok, index_live, _html} = live(conn, Routes.container_index_path(conn, :index))
assert index_live |> element(~s/a[aria-label="Edit #{container.name}"]/) |> render_click() =~
gettext("Edit %{name}", name: container.name)
"Edit #{container.name}"
assert_patch(index_live, Routes.container_index_path(conn, :edit, container))
# assert index_live
# |> form("#container-form", container: @invalid_attrs)
# |> render_change() =~ dgettext("errors", "can't be blank")
assert index_live
|> form("#container-form")
|> render_change(container: @invalid_attrs) =~ "can&#39;t be blank"
{:ok, _view, html} =
index_live
|> form("#container-form", container: @update_attrs)
|> render_submit()
|> form("#container-form")
|> render_submit(container: @update_attrs)
|> follow_redirect(conn, Routes.container_index_path(conn, :index))
container = container.id |> Containers.get_container!(current_user)
assert html =~ dgettext("prompts", "%{name} updated successfully", name: container.name)
assert html =~ "#{container.name} updated successfully"
assert html =~ "some updated location"
end
@ -154,23 +148,23 @@ defmodule CanneryWeb.ContainerLiveTest do
{:ok, index_live, _html} = live(conn, Routes.container_index_path(conn, :index))
html = index_live |> element(~s/a[aria-label="Clone #{container.name}"]/) |> render_click()
assert html =~ gettext("New Container")
assert html =~ "New Container"
assert html =~ "some location"
assert_patch(index_live, Routes.container_index_path(conn, :clone, container))
# assert index_live
# |> form("#container-form", container: @invalid_attrs)
# |> render_change() =~ dgettext("errors", "can't be blank")
assert index_live
|> form("#container-form")
|> render_change(container: @invalid_attrs) =~ "can&#39;t be blank"
{:ok, _view, html} =
index_live
|> form("#container-form", container: @create_attrs)
|> render_submit()
|> form("#container-form")
|> render_submit(container: @create_attrs)
|> follow_redirect(conn, Routes.container_index_path(conn, :index))
container = container.id |> Containers.get_container!(current_user)
assert html =~ dgettext("prompts", "%{name} created successfully", name: container.name)
assert html =~ "#{container.name} created successfully"
assert html =~ "some location"
end
@ -182,30 +176,29 @@ defmodule CanneryWeb.ContainerLiveTest do
{:ok, index_live, _html} = live(conn, Routes.container_index_path(conn, :index))
assert index_live |> element(~s/a[aria-label="Clone #{container.name}"]/) |> render_click() =~
gettext("New Container")
"New Container"
assert_patch(index_live, Routes.container_index_path(conn, :clone, container))
# assert index_live
# |> form("#container-form", container: @invalid_attrs)
# |> render_change() =~ dgettext("errors", "can't be blank")
assert index_live
|> form("#container-form")
|> render_change(container: @invalid_attrs) =~ "can&#39;t be blank"
{:ok, _view, html} =
index_live
|> form("#container-form",
|> form("#container-form")
|> render_submit(
container: Map.merge(@create_attrs, %{location: "some updated location"})
)
|> render_submit()
|> follow_redirect(conn, Routes.container_index_path(conn, :index))
container = container.id |> Containers.get_container!(current_user)
assert html =~ dgettext("prompts", "%{name} created successfully", name: container.name)
assert html =~ "#{container.name} created successfully"
assert html =~ "some updated location"
end
test "deletes container in listing", %{conn: conn, container: container} do
{:ok, index_live, _html} = live(conn, Routes.container_index_path(conn, :index))
assert index_live |> element(~s/a[aria-label="Delete #{container.name}"]/) |> render_click()
refute has_element?(index_live, "#container-#{container.id}")
end
@ -219,7 +212,6 @@ defmodule CanneryWeb.ContainerLiveTest do
container: %{name: name, location: location} = container
} do
{:ok, _show_live, html} = live(conn, Routes.container_show_path(conn, :show, container))
assert html =~ name
assert html =~ location
end
@ -232,84 +224,84 @@ defmodule CanneryWeb.ContainerLiveTest do
{:ok, show_live, _html} = live(conn, Routes.container_show_path(conn, :show, container))
assert show_live |> element(~s/a[aria-label="Edit #{container.name}"]/) |> render_click() =~
gettext("Edit %{name}", name: container.name)
"Edit #{container.name}"
assert_patch(show_live, Routes.container_show_path(conn, :edit, container))
# assert show_live
# |> form("#container-form", container: @invalid_attrs)
# |> render_change() =~ dgettext("errors", "can't be blank")
assert show_live
|> form("#container-form")
|> render_change(container: @invalid_attrs) =~ "can&#39;t be blank"
{:ok, _view, html} =
show_live
|> form("#container-form", container: @update_attrs)
|> render_submit()
|> form("#container-form")
|> render_submit(container: @update_attrs)
|> follow_redirect(conn, Routes.container_show_path(conn, :show, container))
container = container.id |> Containers.get_container!(current_user)
assert html =~ dgettext("prompts", "%{name} updated successfully", name: container.name)
assert html =~ "#{container.name} updated successfully"
assert html =~ "some updated location"
end
test "can sort by type",
%{conn: conn, container: container, current_user: current_user} do
rifle_type = ammo_type_fixture(%{"type" => "rifle"}, current_user)
{1, [rifle_ammo_group]} = ammo_group_fixture(rifle_type, container, current_user)
shotgun_type = ammo_type_fixture(%{"type" => "shotgun"}, current_user)
{1, [shotgun_ammo_group]} = ammo_group_fixture(shotgun_type, container, current_user)
pistol_type = ammo_type_fixture(%{"type" => "pistol"}, current_user)
{1, [pistol_ammo_group]} = ammo_group_fixture(pistol_type, container, current_user)
rifle_type = ammo_type_fixture(%{class: :rifle}, current_user)
{1, [rifle_pack]} = pack_fixture(rifle_type, container, current_user)
shotgun_type = ammo_type_fixture(%{class: :shotgun}, current_user)
{1, [shotgun_pack]} = pack_fixture(shotgun_type, container, current_user)
pistol_type = ammo_type_fixture(%{class: :pistol}, current_user)
{1, [pistol_pack]} = pack_fixture(pistol_type, container, current_user)
{:ok, index_live, html} = live(conn, Routes.container_show_path(conn, :show, container))
assert html =~ "All"
assert html =~ rifle_ammo_group.ammo_type.name
assert html =~ shotgun_ammo_group.ammo_type.name
assert html =~ pistol_ammo_group.ammo_type.name
assert html =~ rifle_pack.ammo_type.name
assert html =~ shotgun_pack.ammo_type.name
assert html =~ pistol_pack.ammo_type.name
html =
index_live
|> form(~s/form[phx-change="change_type"]/)
|> render_change(ammo_type: %{type: :rifle})
|> form(~s/form[phx-change="change_class"]/)
|> render_change(ammo_type: %{class: :rifle})
assert html =~ rifle_ammo_group.ammo_type.name
refute html =~ shotgun_ammo_group.ammo_type.name
refute html =~ pistol_ammo_group.ammo_type.name
assert html =~ rifle_pack.ammo_type.name
refute html =~ shotgun_pack.ammo_type.name
refute html =~ pistol_pack.ammo_type.name
html =
index_live
|> form(~s/form[phx-change="change_type"]/)
|> render_change(ammo_type: %{type: :shotgun})
|> form(~s/form[phx-change="change_class"]/)
|> render_change(ammo_type: %{class: :shotgun})
refute html =~ rifle_ammo_group.ammo_type.name
assert html =~ shotgun_ammo_group.ammo_type.name
refute html =~ pistol_ammo_group.ammo_type.name
refute html =~ rifle_pack.ammo_type.name
assert html =~ shotgun_pack.ammo_type.name
refute html =~ pistol_pack.ammo_type.name
html =
index_live
|> form(~s/form[phx-change="change_type"]/)
|> render_change(ammo_type: %{type: :pistol})
|> form(~s/form[phx-change="change_class"]/)
|> render_change(ammo_type: %{class: :pistol})
refute html =~ rifle_ammo_group.ammo_type.name
refute html =~ shotgun_ammo_group.ammo_type.name
assert html =~ pistol_ammo_group.ammo_type.name
refute html =~ rifle_pack.ammo_type.name
refute html =~ shotgun_pack.ammo_type.name
assert html =~ pistol_pack.ammo_type.name
html =
index_live
|> form(~s/form[phx-change="change_type"]/)
|> render_change(ammo_type: %{type: :all})
|> form(~s/form[phx-change="change_class"]/)
|> render_change(ammo_type: %{class: :all})
assert html =~ rifle_ammo_group.ammo_type.name
assert html =~ shotgun_ammo_group.ammo_type.name
assert html =~ pistol_ammo_group.ammo_type.name
assert html =~ rifle_pack.ammo_type.name
assert html =~ shotgun_pack.ammo_type.name
assert html =~ pistol_pack.ammo_type.name
end
end
describe "Show with ammo group" do
setup [:register_and_log_in_user, :create_container, :create_ammo_group]
describe "Show with pack" do
setup [:register_and_log_in_user, :create_container, :create_pack]
test "displays ammo group",
test "displays pack",
%{conn: conn, ammo_type: %{name: ammo_type_name}, container: container} do
{:ok, _show_live, html} = live(conn, Routes.container_show_path(conn, :show, container))
@ -317,7 +309,7 @@ defmodule CanneryWeb.ContainerLiveTest do
assert html =~ "\n20\n"
end
test "displays ammo group in table",
test "displays pack in table",
%{conn: conn, ammo_type: %{name: ammo_type_name}, container: container} do
{:ok, show_live, _html} = live(conn, Routes.container_show_path(conn, :show, container))

View File

@ -5,14 +5,13 @@ defmodule CanneryWeb.HomeLiveTest do
use CanneryWeb.ConnCase
import Phoenix.LiveViewTest
import CanneryWeb.Gettext
@moduletag :home_live_test
test "disconnected and connected render", %{conn: conn} do
{:ok, home_live, disconnected_html} = live(conn, "/")
assert disconnected_html =~ gettext("Welcome to %{name}", name: "Cannery")
assert render(home_live) =~ gettext("Welcome to %{name}", name: "Cannery")
assert disconnected_html =~ "Welcome to Cannery"
assert render(home_live) =~ "Welcome to Cannery"
end
test "displays version number", %{conn: conn} do

View File

@ -5,13 +5,12 @@ defmodule CanneryWeb.InviteLiveTest do
use CanneryWeb.ConnCase
import Phoenix.LiveViewTest
import CanneryWeb.Gettext
alias Cannery.Accounts.Invites
@moduletag :invite_live_test
@create_attrs %{"name" => "some name"}
@update_attrs %{"name" => "some updated name"}
# @invalid_attrs %{"name" => nil}
@create_attrs %{name: "some name"}
@update_attrs %{name: "some updated name"}
@invalid_attrs %{name: nil}
describe "Index" do
setup [:register_and_log_in_user]
@ -24,32 +23,27 @@ defmodule CanneryWeb.InviteLiveTest do
test "lists all invites", %{conn: conn, invite: invite} do
{:ok, _index_live, html} = live(conn, Routes.invite_index_path(conn, :index))
assert html =~ gettext("Invites")
assert html =~ "Invites"
assert html =~ invite.name
end
test "saves new invite", %{conn: conn} do
{:ok, index_live, _html} = live(conn, Routes.invite_index_path(conn, :index))
assert index_live |> element("a", dgettext("actions", "Create Invite")) |> render_click() =~
gettext("New Invite")
assert index_live |> element("a", "Create Invite") |> render_click() =~ "New Invite"
assert_patch(index_live, Routes.invite_index_path(conn, :new))
# assert index_live
# |> form("#invite-form", invite: @invalid_attrs)
# |> render_change() =~ dgettext("errors", "can't be blank")
assert index_live
|> form("#invite-form")
|> render_change(invite: @invalid_attrs) =~ "can&#39;t be blank"
{:ok, _live, html} =
index_live
|> form("#invite-form", invite: @create_attrs)
|> render_submit()
|> form("#invite-form")
|> render_submit(invite: @create_attrs)
|> follow_redirect(conn, Routes.invite_index_path(conn, :index))
assert html =~
dgettext("prompts", "%{invite_name} created successfully", invite_name: "some name")
assert html =~ "some name"
assert html =~ "some name created successfully"
end
test "updates invite in listing", %{conn: conn, invite: invite} do
@ -57,27 +51,21 @@ defmodule CanneryWeb.InviteLiveTest do
assert index_live
|> element(~s/a[aria-label="Edit invite for #{invite.name}"]/)
|> render_click() =~
gettext("Edit Invite")
|> render_click() =~ "Edit Invite"
assert_patch(index_live, Routes.invite_index_path(conn, :edit, invite))
# assert index_live
# |> form("#invite-form", invite: @invalid_attrs)
# |> render_change() =~ dgettext("errors", "can't be blank")
assert index_live
|> form("#invite-form")
|> render_change(invite: @invalid_attrs) =~ "can&#39;t be blank"
{:ok, _live, html} =
index_live
|> form("#invite-form", invite: @update_attrs)
|> render_submit()
|> form("#invite-form")
|> render_submit(invite: @update_attrs)
|> follow_redirect(conn, Routes.invite_index_path(conn, :index))
assert html =~
dgettext("prompts", "%{invite_name} updated successfully",
invite_name: "some updated name"
)
assert html =~ "some updated name"
assert html =~ "some updated name updated successfully"
end
test "deletes invite in listing", %{conn: conn, invite: invite} do

View File

@ -0,0 +1,459 @@
defmodule CanneryWeb.PackLiveTest do
@moduledoc """
Tests pack live pages
"""
use CanneryWeb.ConnCase
import Phoenix.LiveViewTest
alias Cannery.{Ammo, Repo}
@moduletag :pack_live_test
@create_attrs %{count: 42, notes: "some notes", price_paid: 120.5}
@update_attrs %{count: 43, notes: "some updated notes", price_paid: 456.7}
@invalid_attrs %{count: nil, notes: nil, price_paid: nil}
@pack_create_limit 10_000
@shot_group_create_attrs %{ammo_left: 5, notes: "some notes"}
@shot_group_update_attrs %{
count: 5,
date: ~N[2022-02-13 03:17:00],
notes: "some updated notes"
}
@shot_group_invalid_attrs %{ammo_left: nil, count: nil, notes: nil}
@empty_attrs %{
price_paid: 50,
count: 20
}
@shot_group_attrs %{
price_paid: 50,
count: 20
}
defp create_pack(%{current_user: current_user}) do
ammo_type = ammo_type_fixture(current_user)
container = container_fixture(current_user)
{1, [pack]} = pack_fixture(@create_attrs, ammo_type, container, current_user)
[ammo_type: ammo_type, pack: pack, container: container]
end
defp create_shot_group(%{current_user: current_user, pack: pack}) do
shot_group = shot_group_fixture(@shot_group_update_attrs, current_user, pack)
pack = pack |> Repo.reload!()
[pack: pack, shot_group: shot_group]
end
defp create_empty_pack(%{
current_user: current_user,
ammo_type: ammo_type,
container: container
}) do
{1, [pack]} = pack_fixture(@empty_attrs, ammo_type, container, current_user)
shot_group = shot_group_fixture(@shot_group_attrs, current_user, pack)
pack = pack |> Repo.reload!()
[empty_pack: pack, shot_group: shot_group]
end
describe "Index of pack" do
setup [:register_and_log_in_user, :create_pack]
test "lists all packs", %{conn: conn, pack: pack} do
{:ok, _index_live, html} = live(conn, Routes.pack_index_path(conn, :index))
pack = pack |> Repo.preload(:ammo_type)
assert html =~ "Ammo"
assert html =~ pack.ammo_type.name
end
test "can sort by type",
%{conn: conn, container: container, current_user: current_user} do
rifle_type = ammo_type_fixture(%{class: :rifle}, current_user)
{1, [rifle_pack]} = pack_fixture(rifle_type, container, current_user)
shotgun_type = ammo_type_fixture(%{class: :shotgun}, current_user)
{1, [shotgun_pack]} = pack_fixture(shotgun_type, container, current_user)
pistol_type = ammo_type_fixture(%{class: :pistol}, current_user)
{1, [pistol_pack]} = pack_fixture(pistol_type, container, current_user)
{:ok, index_live, html} = live(conn, Routes.pack_index_path(conn, :index))
assert html =~ "All"
assert html =~ rifle_pack.ammo_type.name
assert html =~ shotgun_pack.ammo_type.name
assert html =~ pistol_pack.ammo_type.name
html =
index_live
|> form(~s/form[phx-change="change_class"]/)
|> render_change(ammo_type: %{class: :rifle})
assert html =~ rifle_pack.ammo_type.name
refute html =~ shotgun_pack.ammo_type.name
refute html =~ pistol_pack.ammo_type.name
html =
index_live
|> form(~s/form[phx-change="change_class"]/)
|> render_change(ammo_type: %{class: :shotgun})
refute html =~ rifle_pack.ammo_type.name
assert html =~ shotgun_pack.ammo_type.name
refute html =~ pistol_pack.ammo_type.name
html =
index_live
|> form(~s/form[phx-change="change_class"]/)
|> render_change(ammo_type: %{class: :pistol})
refute html =~ rifle_pack.ammo_type.name
refute html =~ shotgun_pack.ammo_type.name
assert html =~ pistol_pack.ammo_type.name
html =
index_live
|> form(~s/form[phx-change="change_class"]/)
|> render_change(ammo_type: %{class: :all})
assert html =~ rifle_pack.ammo_type.name
assert html =~ shotgun_pack.ammo_type.name
assert html =~ pistol_pack.ammo_type.name
end
test "can search for packs", %{conn: conn, pack: pack} do
{:ok, index_live, html} = live(conn, Routes.pack_index_path(conn, :index))
pack = pack |> Repo.preload(:ammo_type)
assert html =~ pack.ammo_type.name
assert index_live
|> form(~s/form[phx-change="search"]/)
|> render_change(search: %{search_term: pack.ammo_type.name}) =~
pack.ammo_type.name
assert_patch(
index_live,
Routes.pack_index_path(conn, :search, pack.ammo_type.name)
)
refute index_live
|> form(~s/form[phx-change="search"]/)
|> render_change(search: %{search_term: "something_else"}) =~
pack.ammo_type.name
assert_patch(index_live, Routes.pack_index_path(conn, :search, "something_else"))
assert index_live
|> form(~s/form[phx-change="search"]/)
|> render_change(search: %{search_term: ""}) =~ pack.ammo_type.name
assert_patch(index_live, Routes.pack_index_path(conn, :index))
end
test "saves a single new pack", %{conn: conn} do
{:ok, index_live, _html} = live(conn, Routes.pack_index_path(conn, :index))
assert index_live |> element("a", "Add Ammo") |> render_click() =~ "Add Ammo"
assert_patch(index_live, Routes.pack_index_path(conn, :new))
assert index_live
|> form("#pack-form")
|> render_change(pack: @invalid_attrs) =~ "can&#39;t be blank"
{:ok, _view, html} =
index_live
|> form("#pack-form")
|> render_submit(pack: @create_attrs)
|> follow_redirect(conn, Routes.pack_index_path(conn, :index))
assert html =~ "Ammo added successfully"
assert html =~ "\n42\n"
end
test "saves multiple new packs", %{conn: conn, current_user: current_user} do
multiplier = 25
{:ok, index_live, _html} = live(conn, Routes.pack_index_path(conn, :index))
assert index_live |> element("a", "Add Ammo") |> render_click() =~ "Add Ammo"
assert_patch(index_live, Routes.pack_index_path(conn, :new))
assert index_live
|> form("#pack-form")
|> render_change(pack: @invalid_attrs) =~ "can&#39;t be blank"
{:ok, _view, html} =
index_live
|> form("#pack-form")
|> render_submit(pack: @create_attrs |> Map.put(:multiplier, multiplier))
|> follow_redirect(conn, Routes.pack_index_path(conn, :index))
assert html =~ "Ammo added successfully"
assert Ammo.list_packs(nil, :all, current_user) |> Enum.count() == multiplier + 1
end
test "does not save invalid number of new packs", %{conn: conn} do
{:ok, index_live, _html} = live(conn, Routes.pack_index_path(conn, :index))
assert index_live |> element("a", "Add Ammo") |> render_click() =~ "Add Ammo"
assert_patch(index_live, Routes.pack_index_path(conn, :new))
assert index_live
|> form("#pack-form")
|> render_change(pack: @invalid_attrs) =~ "can&#39;t be blank"
assert index_live
|> form("#pack-form")
|> render_submit(pack: @create_attrs |> Map.put(:multiplier, "0")) =~
"Invalid number of copies, must be between 1 and #{@pack_create_limit}. Was 0"
assert index_live
|> form("#pack-form")
|> render_submit(pack: @create_attrs |> Map.put(:multiplier, @pack_create_limit + 1)) =~
"Invalid number of copies, must be between 1 and #{@pack_create_limit}. Was #{@pack_create_limit + 1}"
end
test "updates pack in listing", %{conn: conn, pack: pack} do
{:ok, index_live, _html} = live(conn, Routes.pack_index_path(conn, :index))
assert index_live
|> element(~s/a[aria-label="Edit pack of #{pack.count} bullets"]/)
|> render_click() =~ "Edit ammo"
assert_patch(index_live, Routes.pack_index_path(conn, :edit, pack))
assert index_live
|> form("#pack-form")
|> render_change(pack: @invalid_attrs) =~ "can&#39;t be blank"
{:ok, _view, html} =
index_live
|> form("#pack-form")
|> render_submit(pack: @update_attrs)
|> follow_redirect(conn, Routes.pack_index_path(conn, :index))
assert html =~ "Ammo updated successfully"
assert html =~ "\n43\n"
end
test "clones pack in listing", %{conn: conn, pack: pack} do
{:ok, index_live, _html} = live(conn, Routes.pack_index_path(conn, :index))
html =
index_live
|> element(~s/a[aria-label="Clone pack of #{pack.count} bullets"]/)
|> render_click()
assert html =~ "Add Ammo"
assert html =~ "$#{display_currency(120.5)}"
assert_patch(index_live, Routes.pack_index_path(conn, :clone, pack))
{:ok, _index_live, html} =
index_live
|> form("#pack-form")
|> render_submit()
|> follow_redirect(conn, Routes.pack_index_path(conn, :index))
assert html =~ "Ammo added successfully"
assert html =~ "\n42\n"
assert html =~ "$#{display_currency(120.5)}"
end
test "checks validity when cloning", %{conn: conn, pack: pack} do
{:ok, index_live, _html} = live(conn, Routes.pack_index_path(conn, :index))
html =
index_live
|> element(~s/a[aria-label="Clone pack of #{pack.count} bullets"]/)
|> render_click()
assert html =~ "Add Ammo"
assert html =~ "$#{display_currency(120.5)}"
assert_patch(index_live, Routes.pack_index_path(conn, :clone, pack))
assert index_live
|> form("#pack-form")
|> render_change(pack: @invalid_attrs) =~ "can&#39;t be blank"
end
test "clones pack in listing with updates", %{conn: conn, pack: pack} do
{:ok, index_live, _html} = live(conn, Routes.pack_index_path(conn, :index))
html =
index_live
|> element(~s/a[aria-label="Clone pack of #{pack.count} bullets"]/)
|> render_click()
assert html =~ "Add Ammo"
assert html =~ "$#{display_currency(120.5)}"
assert_patch(index_live, Routes.pack_index_path(conn, :clone, pack))
assert index_live
|> form("#pack-form")
|> render_change(pack: @invalid_attrs) =~ "can&#39;t be blank"
{:ok, _view, html} =
index_live
|> form("#pack-form")
|> render_submit(pack: @create_attrs |> Map.put(:count, 43))
|> follow_redirect(conn, Routes.pack_index_path(conn, :index))
assert html =~ "Ammo added successfully"
assert html =~ "\n43\n"
assert html =~ "$#{display_currency(120.5)}"
end
test "deletes pack in listing", %{conn: conn, pack: pack} do
{:ok, index_live, _html} = live(conn, Routes.pack_index_path(conn, :index))
assert index_live
|> element(~s/a[aria-label="Delete pack of #{pack.count} bullets"]/)
|> render_click()
refute has_element?(index_live, "#pack-#{pack.id}")
end
test "saves new shot_group", %{conn: conn, pack: pack} do
{:ok, index_live, _html} = live(conn, Routes.pack_index_path(conn, :index))
assert index_live |> element("a", "Record shots") |> render_click() =~ "Record shots"
assert_patch(index_live, Routes.pack_index_path(conn, :add_shot_group, pack))
assert index_live
|> form("#shot-group-form")
|> render_change(shot_group: @shot_group_invalid_attrs) =~ "can&#39;t be blank"
{:ok, _view, html} =
index_live
|> form("#shot-group-form")
|> render_submit(shot_group: @shot_group_create_attrs)
|> follow_redirect(conn, Routes.pack_index_path(conn, :index))
assert html =~ "Shots recorded successfully"
end
@spec display_currency(float()) :: String.t()
defp display_currency(float), do: :erlang.float_to_binary(float, decimals: 2)
end
describe "Index of empty pack" do
setup [:register_and_log_in_user, :create_pack, :create_empty_pack]
test "hides empty packs by default", %{
conn: conn,
empty_pack: pack,
current_user: current_user
} do
{:ok, show_live, html} = live(conn, Routes.pack_index_path(conn, :index))
assert html =~ "Show used"
refute html =~ "$#{display_currency(50.00)}"
percentage = pack |> Ammo.get_percentage_remaining(current_user)
refute html =~ "\n#{"#{percentage}%"}\n"
html =
show_live
|> element(~s/input[type="checkbox"][aria-labelledby="toggle_show_used-label"}]/)
|> render_click()
assert html =~ "$#{display_currency(50.00)}"
percentage = pack |> Ammo.get_percentage_remaining(current_user)
assert html =~ "\n#{"#{percentage}%"}\n"
end
end
describe "Show pack" do
setup [:register_and_log_in_user, :create_pack]
test "displays pack", %{conn: conn, pack: pack} do
{:ok, _show_live, html} = live(conn, Routes.pack_show_path(conn, :show, pack))
pack = pack |> Repo.preload(:ammo_type)
assert html =~ "Show Ammo"
assert html =~ pack.ammo_type.name
end
test "updates pack within modal", %{conn: conn, pack: pack} do
{:ok, show_live, _html} = live(conn, Routes.pack_show_path(conn, :show, pack))
assert show_live
|> element(~s/a[aria-label="Edit pack of #{pack.count} bullets"]/)
|> render_click() =~ "Edit Ammo"
assert_patch(show_live, Routes.pack_show_path(conn, :edit, pack))
assert show_live
|> form("#pack-form")
|> render_change(pack: @invalid_attrs) =~ "can&#39;t be blank"
{:ok, _view, html} =
show_live
|> form("#pack-form")
|> render_submit(pack: @update_attrs)
|> follow_redirect(conn, Routes.pack_show_path(conn, :show, pack))
assert html =~ "Ammo updated successfully"
assert html =~ "some updated notes"
end
test "saves new shot_group", %{conn: conn, pack: pack} do
{:ok, index_live, _html} = live(conn, Routes.pack_show_path(conn, :show, pack))
assert index_live |> element("a", "Record shots") |> render_click() =~ "Record shots"
assert_patch(index_live, Routes.pack_show_path(conn, :add_shot_group, pack))
assert index_live
|> form("#shot-group-form")
|> render_change(shot_group: @shot_group_invalid_attrs) =~ "can&#39;t be blank"
{:ok, _view, html} =
index_live
|> form("#shot-group-form")
|> render_submit(shot_group: @shot_group_create_attrs)
|> follow_redirect(conn, Routes.pack_show_path(conn, :show, pack))
assert html =~ "Shots recorded successfully"
end
end
describe "Show pack with shot group" do
setup [:register_and_log_in_user, :create_pack, :create_shot_group]
test "updates shot_group in listing",
%{conn: conn, pack: pack, shot_group: shot_group} do
{:ok, index_live, _html} = live(conn, Routes.pack_show_path(conn, :edit, pack))
assert index_live
|> element(~s/a[aria-label="Edit shot group of #{shot_group.count} shots"]/)
|> render_click() =~ "Edit Shot Records"
assert_patch(
index_live,
Routes.pack_show_path(conn, :edit_shot_group, pack, shot_group)
)
assert index_live
|> form("#shot-group-form")
|> render_change(shot_group: @shot_group_invalid_attrs) =~ "can&#39;t be blank"
{:ok, _view, html} =
index_live
|> form("#shot-group-form")
|> render_submit(shot_group: @shot_group_update_attrs)
|> follow_redirect(conn, Routes.pack_show_path(conn, :show, pack))
assert html =~ "Shot records updated successfully"
assert html =~ "some updated notes"
end
test "deletes shot_group in listing",
%{conn: conn, pack: pack, shot_group: shot_group} do
{:ok, index_live, _html} =
live(conn, Routes.pack_show_path(conn, :edit_shot_group, pack, shot_group))
assert index_live
|> element(~s/a[aria-label="Delete shot record of #{shot_group.count} shots"]/)
|> render_click()
refute has_element?(index_live, "#shot_group-#{shot_group.id}")
end
end
end

View File

@ -6,28 +6,26 @@ defmodule CanneryWeb.RangeLiveTest do
use CanneryWeb.ConnCase
import Phoenix.LiveViewTest
import Cannery.Fixtures
import CanneryWeb.Gettext
@moduletag :range_live_test
@create_attrs %{"ammo_left" => 5, "notes" => "some notes"}
@update_attrs %{"count" => 16, "notes" => "some updated notes"}
# @invalid_attrs %{"count" => nil, "notes" => nil}
@create_attrs %{ammo_left: 5, notes: "some notes"}
@update_attrs %{count: 16, notes: "some updated notes"}
@invalid_attrs %{count: nil, notes: nil}
defp create_shot_group(%{current_user: current_user}) do
container = container_fixture(%{"staged" => true}, current_user)
container = container_fixture(%{staged: true}, current_user)
ammo_type = ammo_type_fixture(current_user)
{1, [ammo_group]} =
ammo_group_fixture(%{"staged" => true}, ammo_type, container, current_user)
{1, [pack]} = pack_fixture(%{staged: true}, ammo_type, container, current_user)
shot_group =
%{"count" => 5, "date" => ~N[2022-02-13 03:17:00], "notes" => "some notes"}
|> shot_group_fixture(current_user, ammo_group)
%{count: 5, date: ~N[2022-02-13 03:17:00], notes: "some notes"}
|> shot_group_fixture(current_user, pack)
[
container: container,
ammo_type: ammo_type,
ammo_group: ammo_group,
pack: pack,
shot_group: shot_group
]
end
@ -38,29 +36,26 @@ defmodule CanneryWeb.RangeLiveTest do
test "lists all shot_groups", %{conn: conn, shot_group: shot_group} do
{:ok, _index_live, html} = live(conn, Routes.range_index_path(conn, :index))
assert html =~ gettext("Range day")
assert html =~ "Range day"
assert html =~ shot_group.notes
end
test "can sort by type",
%{conn: conn, container: container, current_user: current_user} do
rifle_ammo_type = ammo_type_fixture(%{"type" => "rifle"}, current_user)
{1, [rifle_ammo_group]} = ammo_group_fixture(rifle_ammo_type, container, current_user)
rifle_ammo_type = ammo_type_fixture(%{class: :rifle}, current_user)
{1, [rifle_pack]} = pack_fixture(rifle_ammo_type, container, current_user)
rifle_shot_group =
shot_group_fixture(%{"notes" => "group_one"}, current_user, rifle_ammo_group)
rifle_shot_group = shot_group_fixture(%{notes: "group_one"}, current_user, rifle_pack)
shotgun_ammo_type = ammo_type_fixture(%{"type" => "shotgun"}, current_user)
{1, [shotgun_ammo_group]} = ammo_group_fixture(shotgun_ammo_type, container, current_user)
shotgun_ammo_type = ammo_type_fixture(%{class: :shotgun}, current_user)
{1, [shotgun_pack]} = pack_fixture(shotgun_ammo_type, container, current_user)
shotgun_shot_group =
shot_group_fixture(%{"notes" => "group_two"}, current_user, shotgun_ammo_group)
shotgun_shot_group = shot_group_fixture(%{notes: "group_two"}, current_user, shotgun_pack)
pistol_ammo_type = ammo_type_fixture(%{"type" => "pistol"}, current_user)
{1, [pistol_ammo_group]} = ammo_group_fixture(pistol_ammo_type, container, current_user)
pistol_ammo_type = ammo_type_fixture(%{class: :pistol}, current_user)
{1, [pistol_pack]} = pack_fixture(pistol_ammo_type, container, current_user)
pistol_shot_group =
shot_group_fixture(%{"notes" => "group_three"}, current_user, pistol_ammo_group)
pistol_shot_group = shot_group_fixture(%{notes: "group_three"}, current_user, pistol_pack)
{:ok, index_live, html} = live(conn, Routes.range_index_path(conn, :index))
@ -72,8 +67,8 @@ defmodule CanneryWeb.RangeLiveTest do
html =
index_live
|> form(~s/form[phx-change="change_type"]/)
|> render_change(ammo_type: %{type: :rifle})
|> form(~s/form[phx-change="change_class"]/)
|> render_change(ammo_type: %{class: :rifle})
assert html =~ rifle_shot_group.notes
refute html =~ shotgun_shot_group.notes
@ -81,8 +76,8 @@ defmodule CanneryWeb.RangeLiveTest do
html =
index_live
|> form(~s/form[phx-change="change_type"]/)
|> render_change(ammo_type: %{type: :shotgun})
|> form(~s/form[phx-change="change_class"]/)
|> render_change(ammo_type: %{class: :shotgun})
refute html =~ rifle_shot_group.notes
assert html =~ shotgun_shot_group.notes
@ -90,8 +85,8 @@ defmodule CanneryWeb.RangeLiveTest do
html =
index_live
|> form(~s/form[phx-change="change_type"]/)
|> render_change(ammo_type: %{type: :pistol})
|> form(~s/form[phx-change="change_class"]/)
|> render_change(ammo_type: %{class: :pistol})
refute html =~ rifle_shot_group.notes
refute html =~ shotgun_shot_group.notes
@ -99,8 +94,8 @@ defmodule CanneryWeb.RangeLiveTest do
html =
index_live
|> form(~s/form[phx-change="change_type"]/)
|> render_change(ammo_type: %{type: :all})
|> form(~s/form[phx-change="change_class"]/)
|> render_change(ammo_type: %{class: :all})
assert html =~ rifle_shot_group.notes
assert html =~ shotgun_shot_group.notes
@ -113,45 +108,41 @@ defmodule CanneryWeb.RangeLiveTest do
assert html =~ shot_group.notes
assert index_live
|> form(~s/form[phx-change="search"]/,
search: %{search_term: shot_group.notes}
)
|> render_change() =~ shot_group.notes
|> form(~s/form[phx-change="search"]/)
|> render_change(search: %{search_term: shot_group.notes}) =~ shot_group.notes
assert_patch(index_live, Routes.range_index_path(conn, :search, shot_group.notes))
refute index_live
|> form(~s/form[phx-change="search"]/, search: %{search_term: "something_else"})
|> render_change() =~ shot_group.notes
|> form(~s/form[phx-change="search"]/)
|> render_change(search: %{search_term: "something_else"}) =~ shot_group.notes
assert_patch(index_live, Routes.range_index_path(conn, :search, "something_else"))
assert index_live
|> form(~s/form[phx-change="search"]/, search: %{search_term: ""})
|> render_change() =~ shot_group.notes
|> form(~s/form[phx-change="search"]/)
|> render_change(search: %{search_term: ""}) =~ shot_group.notes
assert_patch(index_live, Routes.range_index_path(conn, :index))
end
test "saves new shot_group", %{conn: conn, ammo_group: ammo_group} do
test "saves new shot_group", %{conn: conn, pack: pack} do
{:ok, index_live, _html} = live(conn, Routes.range_index_path(conn, :index))
assert index_live |> element("a", dgettext("actions", "Record shots")) |> render_click() =~
gettext("Record shots")
assert index_live |> element("a", "Record shots") |> render_click() =~ "Record shots"
assert_patch(index_live, Routes.range_index_path(conn, :add_shot_group, pack))
assert_patch(index_live, Routes.range_index_path(conn, :add_shot_group, ammo_group))
# assert index_live
# |> form("#shot_group-form", shot_group: @invalid_attrs)
# |> render_change() =~ dgettext("errors", "is invalid")
assert index_live
|> form("#shot-group-form")
|> render_change(shot_group: @invalid_attrs) =~ "can&#39;t be blank"
{:ok, _view, html} =
index_live
|> form("#shot-group-form", shot_group: @create_attrs)
|> render_submit()
|> form("#shot-group-form")
|> render_submit(shot_group: @create_attrs)
|> follow_redirect(conn, Routes.range_index_path(conn, :index))
assert html =~ dgettext("prompts", "Shots recorded successfully")
assert html =~ "Shots recorded successfully"
assert html =~ "some notes"
end
@ -160,14 +151,13 @@ defmodule CanneryWeb.RangeLiveTest do
assert index_live
|> element(~s/a[aria-label="Edit shot record of #{shot_group.count} shots"]/)
|> render_click() =~
gettext("Edit Shot Records")
|> render_click() =~ "Edit Shot Records"
assert_patch(index_live, Routes.range_index_path(conn, :edit, shot_group))
# assert index_live
# |> form("#shot_group-form", shot_group: @invalid_attrs)
# |> render_change() =~ dgettext("errors", "is invalid")
assert index_live
|> form("#shot-group-form")
|> render_change(shot_group: @invalid_attrs) =~ "can&#39;t be blank"
{:ok, _view, html} =
index_live
@ -175,7 +165,7 @@ defmodule CanneryWeb.RangeLiveTest do
|> render_submit()
|> follow_redirect(conn, Routes.range_index_path(conn, :index))
assert html =~ dgettext("actions", "Shot records updated successfully")
assert html =~ "Shot records updated successfully"
assert html =~ "some updated notes"
end

View File

@ -5,26 +5,24 @@ defmodule CanneryWeb.TagLiveTest do
use CanneryWeb.ConnCase
import Phoenix.LiveViewTest
import CanneryWeb.Gettext
@moduletag :tag_live_test
@create_attrs %{
"bg_color" => "#100000",
"name" => "some name",
"text_color" => "#000000"
bg_color: "#100000",
name: "some name",
text_color: "#000000"
}
@update_attrs %{
"bg_color" => "#100001",
"name" => "some updated name",
"text_color" => "#000001"
bg_color: "#100001",
name: "some updated name",
text_color: "#000001"
}
@invalid_attrs %{
bg_color: nil,
name: nil,
text_color: nil
}
# @invalid_attrs %{
# "bg_color" => nil,
# "name" => nil,
# "text_color" => nil
# }
def create_tag(%{current_user: current_user}) do
tag = tag_fixture(current_user)
@ -37,7 +35,7 @@ defmodule CanneryWeb.TagLiveTest do
test "lists all tags", %{conn: conn, tag: tag} do
{:ok, _index_live, html} = live(conn, Routes.tag_index_path(conn, :index))
assert html =~ gettext("Tags")
assert html =~ "Tags"
assert html =~ tag.bg_color
end
@ -47,22 +45,20 @@ defmodule CanneryWeb.TagLiveTest do
assert html =~ tag.name
assert index_live
|> form(~s/form[phx-change="search"]/,
search: %{search_term: tag.name}
)
|> render_change() =~ tag.name
|> form(~s/form[phx-change="search"]/)
|> render_change(search: %{search_term: tag.name}) =~ tag.name
assert_patch(index_live, Routes.tag_index_path(conn, :search, tag.name))
refute index_live
|> form(~s/form[phx-change="search"]/, search: %{search_term: "something_else"})
|> render_change() =~ tag.name
|> form(~s/form[phx-change="search"]/)
|> render_change(search: %{search_term: "something_else"}) =~ tag.name
assert_patch(index_live, Routes.tag_index_path(conn, :search, "something_else"))
assert index_live
|> form(~s/form[phx-change="search"]/, search: %{search_term: ""})
|> render_change() =~ tag.name
|> form(~s/form[phx-change="search"]/)
|> render_change(search: %{search_term: ""}) =~ tag.name
assert_patch(index_live, Routes.tag_index_path(conn, :index))
end
@ -70,22 +66,20 @@ defmodule CanneryWeb.TagLiveTest do
test "saves new tag", %{conn: conn} do
{:ok, index_live, _html} = live(conn, Routes.tag_index_path(conn, :index))
assert index_live |> element("a", dgettext("actions", "New Tag")) |> render_click() =~
dgettext("actions", "New Tag")
assert index_live |> element("a", "New Tag") |> render_click() =~ "New Tag"
assert_patch(index_live, Routes.tag_index_path(conn, :new))
# assert index_live
# |> form("#tag-form", tag: @invalid_attrs)
# |> render_change() =~ dgettext("errors", "can't be blank")
assert index_live
|> form("#tag-form")
|> render_change(tag: @invalid_attrs) =~ "can&#39;t be blank"
{:ok, _view, html} =
index_live
|> form("#tag-form", tag: @create_attrs)
|> render_submit()
|> form("#tag-form")
|> render_submit(tag: @create_attrs)
|> follow_redirect(conn, Routes.tag_index_path(conn, :index))
assert html =~ dgettext("actions", "%{name} created successfully", name: "some name")
assert html =~ "some name created successfully"
assert html =~ "#100000"
end
@ -93,23 +87,21 @@ defmodule CanneryWeb.TagLiveTest do
{:ok, index_live, _html} = live(conn, Routes.tag_index_path(conn, :index))
assert index_live |> element(~s/a[aria-label="Edit #{tag.name}"]/) |> render_click() =~
dgettext("actions", "Edit Tag")
"Edit Tag"
assert_patch(index_live, Routes.tag_index_path(conn, :edit, tag))
# assert index_live
# |> form("#tag-form", tag: @invalid_attrs)
# |> render_change() =~ dgettext("errors", "can't be blank")
assert index_live
|> form("#tag-form")
|> render_change(tag: @invalid_attrs) =~ "can&#39;t be blank"
{:ok, _view, html} =
index_live
|> form("#tag-form", tag: @update_attrs)
|> render_submit()
|> form("#tag-form")
|> render_submit(tag: @update_attrs)
|> follow_redirect(conn, Routes.tag_index_path(conn, :index))
assert html =~
dgettext("prompts", "%{name} updated successfully", name: "some updated name")
assert html =~ "some updated name updated successfully"
assert html =~ "#100001"
end

View File

@ -4,19 +4,16 @@ defmodule CanneryWeb.ErrorViewTest do
"""
use CanneryWeb.ConnCase, async: true
import CanneryWeb.Gettext
# Bring render/3 and render_to_string/3 for testing custom views
import Phoenix.View
@moduletag :error_view_test
test "renders 404.html" do
assert render_to_string(CanneryWeb.ErrorView, "404.html", []) =~
dgettext("errors", "Not found")
assert render_to_string(CanneryWeb.ErrorView, "404.html", []) =~ "Not found"
end
test "renders 500.html" do
assert render_to_string(CanneryWeb.ErrorView, "500.html", []) =~
dgettext("errors", "Internal Server Error")
assert render_to_string(CanneryWeb.ErrorView, "500.html", []) =~ "Internal Server Error"
end
end

View File

@ -10,8 +10,8 @@ defmodule Cannery.Fixtures do
Accounts.User,
ActivityLog.ShotGroup,
Ammo,
Ammo.AmmoGroup,
Ammo.AmmoType,
Ammo.Pack,
Containers,
Containers.Container,
Containers.Tag,
@ -24,8 +24,8 @@ defmodule Cannery.Fixtures do
def user_fixture(attrs \\ %{}) do
attrs
|> Enum.into(%{
"email" => unique_user_email(),
"password" => valid_user_password()
email: unique_user_email(),
password: valid_user_password()
})
|> Accounts.register_user()
|> unwrap_ok_tuple()
@ -36,8 +36,8 @@ defmodule Cannery.Fixtures do
def admin_fixture(attrs \\ %{}) do
attrs
|> Enum.into(%{
"email" => unique_user_email(),
"password" => valid_user_password()
email: unique_user_email(),
password: valid_user_password()
})
|> Accounts.register_user()
|> unwrap_ok_tuple()
@ -71,16 +71,16 @@ defmodule Cannery.Fixtures do
@doc """
Generate a ShotGroup
"""
@spec shot_group_fixture(User.t(), AmmoGroup.t()) :: ShotGroup.t()
@spec shot_group_fixture(attrs :: map(), User.t(), AmmoGroup.t()) :: ShotGroup.t()
def shot_group_fixture(attrs \\ %{}, %User{} = user, %AmmoGroup{} = ammo_group) do
@spec shot_group_fixture(User.t(), Pack.t()) :: ShotGroup.t()
@spec shot_group_fixture(attrs :: map(), User.t(), Pack.t()) :: ShotGroup.t()
def shot_group_fixture(attrs \\ %{}, %User{} = user, %Pack{} = pack) do
attrs
|> Enum.into(%{
"count" => 20,
"date" => ~N[2022-02-13 03:17:00],
"notes" => random_string()
count: 20,
date: ~N[2022-02-13 03:17:00],
notes: random_string()
})
|> Cannery.ActivityLog.create_shot_group(user, ammo_group)
|> Cannery.ActivityLog.create_shot_group(user, pack)
|> unwrap_ok_tuple()
end
@ -91,7 +91,12 @@ defmodule Cannery.Fixtures do
@spec container_fixture(attrs :: map(), User.t()) :: Container.t()
def container_fixture(attrs \\ %{}, %User{} = user) do
attrs
|> Enum.into(%{"name" => random_string(), "type" => "Ammo can"})
|> Enum.into(%{
name: random_string(),
type: "Ammo can",
location: random_string(),
desc: random_string()
})
|> Containers.create_container(user)
|> unwrap_ok_tuple()
end
@ -103,26 +108,59 @@ defmodule Cannery.Fixtures do
@spec ammo_type_fixture(attrs :: map(), User.t()) :: AmmoType.t()
def ammo_type_fixture(attrs \\ %{}, %User{} = user) do
attrs
|> Enum.into(%{"name" => random_string(), "type" => "rifle"})
|> Enum.into(%{
name: random_string(),
class: :rifle,
desc: random_string(),
bullet_type: random_string(),
bullet_core: random_string(),
cartridge: random_string(),
caliber: random_string(),
case_material: random_string(),
jacket_type: random_string(),
muzzle_velocity: 3,
powder_type: random_string(),
powder_grains_per_charge: 5,
grains: 7,
pressure: random_string(),
primer_type: random_string(),
firing_type: random_string(),
wadding: random_string(),
shot_type: random_string(),
shot_material: random_string(),
shot_size: random_string(),
unfired_length: random_string(),
brass_height: random_string(),
chamber_size: random_string(),
load_grains: 9,
shot_charge_weight: random_string(),
dram_equivalent: random_string(),
tracer: false,
incendiary: false,
blank: false,
corrosive: false,
manufacturer: random_string(),
upc: random_string()
})
|> Ammo.create_ammo_type(user)
|> unwrap_ok_tuple()
end
@doc """
Generate a AmmoGroup
Generate a Pack
"""
@spec ammo_group_fixture(AmmoType.t(), Container.t(), User.t()) ::
{count :: non_neg_integer(), [AmmoGroup.t()]}
@spec ammo_group_fixture(attrs :: map(), AmmoType.t(), Container.t(), User.t()) ::
{count :: non_neg_integer(), [AmmoGroup.t()]}
@spec ammo_group_fixture(
@spec pack_fixture(AmmoType.t(), Container.t(), User.t()) ::
{count :: non_neg_integer(), [Pack.t()]}
@spec pack_fixture(attrs :: map(), AmmoType.t(), Container.t(), User.t()) ::
{count :: non_neg_integer(), [Pack.t()]}
@spec pack_fixture(
attrs :: map(),
multiplier :: non_neg_integer(),
AmmoType.t(),
Container.t(),
User.t()
) :: {count :: non_neg_integer(), [AmmoGroup.t()]}
def ammo_group_fixture(
) :: {count :: non_neg_integer(), [Pack.t()]}
def pack_fixture(
attrs \\ %{},
multiplier \\ 1,
%AmmoType{id: ammo_type_id},
@ -131,12 +169,12 @@ defmodule Cannery.Fixtures do
) do
attrs
|> Enum.into(%{
"ammo_type_id" => ammo_type_id,
"container_id" => container_id,
"count" => 20,
"purchased_on" => Date.utc_today()
ammo_type_id: ammo_type_id,
container_id: container_id,
count: 20,
purchased_on: Date.utc_today()
})
|> Ammo.create_ammo_groups(multiplier, user)
|> Ammo.create_packs(multiplier, user)
|> unwrap_ok_tuple()
end
@ -148,9 +186,9 @@ defmodule Cannery.Fixtures do
def tag_fixture(attrs \\ %{}, %User{} = user) do
attrs
|> Enum.into(%{
"bg_color" => "#100000",
"name" => random_string(),
"text_color" => "#000000"
bg_color: "#100000",
name: random_string(),
text_color: "#000000"
})
|> Containers.create_tag(user)
|> unwrap_ok_tuple()