forked from shibao/cannery
add tag editing to containers
This commit is contained in:
parent
146c8e7ab3
commit
4ff2f64a22
8
CHANGELOG.md
Normal file
8
CHANGELOG.md
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# 0.2.0
|
||||||
|
- Add or remove tags from Containers list and details page
|
||||||
|
- Show tags on containers
|
||||||
|
- Add "Cannery" to page titles
|
||||||
|
|
||||||
|
|
||||||
|
# 0.1.0
|
||||||
|
- Initial release!
|
@ -19,8 +19,16 @@ defmodule Cannery.Containers do
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
@spec list_containers(User.t()) :: [Container.t()]
|
@spec list_containers(User.t()) :: [Container.t()]
|
||||||
def list_containers(%User{id: user_id}),
|
def list_containers(%User{id: user_id}) do
|
||||||
do: Repo.all(from c in Container, where: c.user_id == ^user_id, order_by: c.name)
|
Repo.all(
|
||||||
|
from c in Container,
|
||||||
|
left_join: t in assoc(c, :tags),
|
||||||
|
left_join: ag in assoc(c, :ammo_groups),
|
||||||
|
where: c.user_id == ^user_id,
|
||||||
|
order_by: c.name,
|
||||||
|
preload: [tags: t, ammo_groups: ag]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Gets a single container.
|
Gets a single container.
|
||||||
@ -37,8 +45,17 @@ defmodule Cannery.Containers do
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
@spec get_container!(Container.id(), User.t()) :: Container.t()
|
@spec get_container!(Container.id(), User.t()) :: Container.t()
|
||||||
def get_container!(id, %User{id: user_id}),
|
def get_container!(id, %User{id: user_id}) do
|
||||||
do: Repo.one!(from c in Container, where: c.id == ^id and c.user_id == ^user_id)
|
Repo.one!(
|
||||||
|
from c in Container,
|
||||||
|
left_join: t in assoc(c, :tags),
|
||||||
|
left_join: ag in assoc(c, :ammo_groups),
|
||||||
|
where: c.user_id == ^user_id,
|
||||||
|
where: c.id == ^id,
|
||||||
|
order_by: c.name,
|
||||||
|
preload: [tags: t, ammo_groups: ag]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Creates a container.
|
Creates a container.
|
||||||
@ -189,4 +206,17 @@ defmodule Cannery.Containers do
|
|||||||
|
|
||||||
if count == 0, do: raise("could not delete container tag"), else: count
|
if count == 0, do: raise("could not delete container tag"), else: count
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Returns number of rounds in container. If data is already preloaded, then
|
||||||
|
there will be no db hit.
|
||||||
|
"""
|
||||||
|
@spec get_container_rounds!(Container.t()) :: non_neg_integer()
|
||||||
|
def get_container_rounds!(%Container{} = container) do
|
||||||
|
container
|
||||||
|
|> Repo.preload(:ammo_groups)
|
||||||
|
|> Map.get(:ammo_groups)
|
||||||
|
|> Enum.map(fn %{count: count} -> count end)
|
||||||
|
|> Enum.sum()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -4,17 +4,21 @@ defmodule CanneryWeb.Components.ContainerCard do
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
use CanneryWeb, :component
|
use CanneryWeb, :component
|
||||||
|
import CanneryWeb.Components.TagCard
|
||||||
|
alias Cannery.{Repo, Containers}
|
||||||
alias CanneryWeb.Endpoint
|
alias CanneryWeb.Endpoint
|
||||||
|
|
||||||
def container_card(assigns) do
|
def container_card(%{container: container} = assigns) do
|
||||||
|
assigns = assigns |> Map.put(:container, container |> Repo.preload([:tags, :ammo_groups]))
|
||||||
|
|
||||||
~H"""
|
~H"""
|
||||||
<div
|
<div
|
||||||
id={"container-#{@container.id}"}
|
id={"container-#{@container.id}"}
|
||||||
class="mx-4 my-2 px-8 py-4 flex flex-col justify-center items-center
|
class="mx-4 my-2 px-8 py-4 flex flex-col justify-center items-center space-y-4
|
||||||
border border-gray-400 rounded-lg shadow-lg hover:shadow-md
|
border border-gray-400 rounded-lg shadow-lg hover:shadow-md
|
||||||
transition-all duration-300 ease-in-out"
|
transition-all duration-300 ease-in-out"
|
||||||
>
|
>
|
||||||
<div class="mb-4 flex flex-col justify-center items-center">
|
<div class="mb-4 flex flex-col justify-center items-center space-y-2">
|
||||||
<%= live_redirect to: Routes.container_show_path(Endpoint, :show, @container),
|
<%= live_redirect to: Routes.container_show_path(Endpoint, :show, @container),
|
||||||
class: "link" do %>
|
class: "link" do %>
|
||||||
<h1 class="px-4 py-2 rounded-lg title text-xl">
|
<h1 class="px-4 py-2 rounded-lg title text-xl">
|
||||||
@ -40,6 +44,25 @@ defmodule CanneryWeb.Components.ContainerCard do
|
|||||||
<%= @container.location %>
|
<%= @container.location %>
|
||||||
</span>
|
</span>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
<%= if @container.ammo_groups do %>
|
||||||
|
<span class="rounded-lg title text-lg">
|
||||||
|
<%= gettext("Rounds:") %>
|
||||||
|
<%= @container |> Containers.get_container_rounds!() %>
|
||||||
|
</span>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<div class="flex flex-wrap justify-center items-center">
|
||||||
|
<%= unless @container.tags |> Enum.empty?() do %>
|
||||||
|
<%= for tag <- @container.tags do %>
|
||||||
|
<.simple_tag_card tag={tag} />
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<%= if assigns |> Map.has_key?(:tag_actions) do %>
|
||||||
|
<%= render_slot(@tag_actions) %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<%= if assigns |> Map.has_key?(:inner_block) do %>
|
<%= if assigns |> Map.has_key?(:inner_block) do %>
|
||||||
|
@ -13,15 +13,20 @@ defmodule CanneryWeb.Components.TagCard do
|
|||||||
border border-gray-400 rounded-lg shadow-lg hover:shadow-md
|
border border-gray-400 rounded-lg shadow-lg hover:shadow-md
|
||||||
transition-all duration-300 ease-in-out"
|
transition-all duration-300 ease-in-out"
|
||||||
>
|
>
|
||||||
<h1
|
<.simple_tag_card tag={@tag} />
|
||||||
class="px-4 py-2 rounded-lg title text-xl"
|
|
||||||
style={"color: #{@tag.text_color}; background-color: #{@tag.bg_color}"}
|
|
||||||
>
|
|
||||||
<%= @tag.name %>
|
|
||||||
</h1>
|
|
||||||
|
|
||||||
<%= render_slot(@inner_block) %>
|
<%= render_slot(@inner_block) %>
|
||||||
</div>
|
</div>
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def simple_tag_card(assigns) do
|
||||||
|
~H"""
|
||||||
|
<h1
|
||||||
|
class="mx-2 my-1 px-4 py-2 rounded-lg title text-xl"
|
||||||
|
style={"color: #{@tag.text_color}; background-color: #{@tag.bg_color}"}
|
||||||
|
>
|
||||||
|
<%= @tag.name %>
|
||||||
|
</h1>
|
||||||
|
"""
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,51 +0,0 @@
|
|||||||
defmodule CanneryWeb.ContainerLive.AddTagComponent do
|
|
||||||
@moduledoc """
|
|
||||||
Livecomponent that can add a tag to a Container
|
|
||||||
"""
|
|
||||||
|
|
||||||
use CanneryWeb, :live_component
|
|
||||||
alias Cannery.{Accounts.User, Containers, Containers.Container, Tags, Tags.Tag}
|
|
||||||
alias Phoenix.LiveView.Socket
|
|
||||||
|
|
||||||
@impl true
|
|
||||||
@spec update(
|
|
||||||
%{:container => Container.t(), :current_user => User.t(), optional(any) => any},
|
|
||||||
Socket.t()
|
|
||||||
) :: {:ok, Socket.t()}
|
|
||||||
def update(%{container: _container, current_user: current_user} = assigns, socket) do
|
|
||||||
{:ok, socket |> assign(assigns) |> assign(:tags, Tags.list_tags(current_user))}
|
|
||||||
end
|
|
||||||
|
|
||||||
@impl true
|
|
||||||
def handle_event(
|
|
||||||
"save",
|
|
||||||
%{"tag" => %{"tag_id" => tag_id}},
|
|
||||||
%{
|
|
||||||
assigns: %{
|
|
||||||
tags: tags,
|
|
||||||
container: container,
|
|
||||||
current_user: current_user,
|
|
||||||
return_to: return_to
|
|
||||||
}
|
|
||||||
} = socket
|
|
||||||
) do
|
|
||||||
socket =
|
|
||||||
case tags |> Enum.find(fn %{id: id} -> tag_id == id end) do
|
|
||||||
nil ->
|
|
||||||
prompt = dgettext("errors", "Tag could not be added")
|
|
||||||
socket |> put_flash(:error, prompt)
|
|
||||||
|
|
||||||
%{name: tag_name} = tag ->
|
|
||||||
_container_tag = Containers.add_tag!(container, tag, current_user)
|
|
||||||
prompt = dgettext("prompts", "%{name} added successfully", name: tag_name)
|
|
||||||
socket |> put_flash(:info, prompt) |> push_redirect(to: return_to)
|
|
||||||
end
|
|
||||||
|
|
||||||
{:noreply, socket}
|
|
||||||
end
|
|
||||||
|
|
||||||
@spec tag_options([Tag.t()]) :: [{String.t(), Tag.id()}]
|
|
||||||
defp tag_options(tags) do
|
|
||||||
tags |> Enum.map(fn %{id: id, name: name} -> {name, id} end)
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,22 +0,0 @@
|
|||||||
<div>
|
|
||||||
<h2 class="mb-8 text-center title text-xl text-primary-600">
|
|
||||||
<%= @title %>
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
<.form
|
|
||||||
let={f}
|
|
||||||
for={:tag}
|
|
||||||
id="add-tag-to-container-form"
|
|
||||||
class="flex flex-col sm:grid sm:grid-cols-3 sm:gap-4 justify-center items-center"
|
|
||||||
phx-target={@myself}
|
|
||||||
phx-submit="save"
|
|
||||||
>
|
|
||||||
<%= select(f, :tag_id, tag_options(@tags), class: "text-center col-span-2 input input-primary") %>
|
|
||||||
<%= error_tag(f, :tag_id, "col-span-3 text-center") %>
|
|
||||||
|
|
||||||
<%= submit(dgettext("actions", "Add"),
|
|
||||||
class: "mx-auto btn btn-primary",
|
|
||||||
phx_disable_with: dgettext("prompts", "Adding...")
|
|
||||||
) %>
|
|
||||||
</.form>
|
|
||||||
</div>
|
|
73
lib/cannery_web/live/container_live/edit_tags_component.ex
Normal file
73
lib/cannery_web/live/container_live/edit_tags_component.ex
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
defmodule CanneryWeb.ContainerLive.EditTagsComponent do
|
||||||
|
@moduledoc """
|
||||||
|
Livecomponent that can add or remove a tag to a Container
|
||||||
|
"""
|
||||||
|
|
||||||
|
use CanneryWeb, :live_component
|
||||||
|
alias Cannery.{Accounts.User, Containers, Containers.Container, Tags, Tags.Tag, Repo}
|
||||||
|
alias Phoenix.LiveView.Socket
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
@spec update(
|
||||||
|
%{:container => Container.t(), :current_user => User.t(), optional(any) => any},
|
||||||
|
Socket.t()
|
||||||
|
) :: {:ok, Socket.t()}
|
||||||
|
def update(%{container: container, current_user: current_user} = assigns, socket) do
|
||||||
|
tags = Tags.list_tags(current_user)
|
||||||
|
container = container |> Repo.preload(:tags)
|
||||||
|
{:ok, socket |> assign(assigns) |> assign(tags: tags, container: container)}
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def handle_event(
|
||||||
|
"save",
|
||||||
|
%{"tag" => %{"tag_id" => tag_id}},
|
||||||
|
%{assigns: %{tags: tags, container: container, current_user: current_user}} = socket
|
||||||
|
) do
|
||||||
|
socket =
|
||||||
|
case tags |> Enum.find(fn %{id: id} -> tag_id == id end) do
|
||||||
|
nil ->
|
||||||
|
prompt = dgettext("errors", "Tag could not be added")
|
||||||
|
socket |> put_flash(:error, prompt)
|
||||||
|
|
||||||
|
%{name: tag_name} = tag ->
|
||||||
|
_container_tag = Containers.add_tag!(container, tag, current_user)
|
||||||
|
container = container |> Repo.preload(:tags, force: true)
|
||||||
|
prompt = dgettext("prompts", "%{name} added successfully", name: tag_name)
|
||||||
|
socket |> put_flash(:info, prompt) |> assign(container: container)
|
||||||
|
end
|
||||||
|
|
||||||
|
{:noreply, socket}
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def handle_event(
|
||||||
|
"delete",
|
||||||
|
%{"tag-id" => tag_id},
|
||||||
|
%{assigns: %{tags: tags, container: container, current_user: current_user}} = socket
|
||||||
|
) do
|
||||||
|
socket =
|
||||||
|
case tags |> Enum.find(fn %{id: id} -> tag_id == id end) do
|
||||||
|
nil ->
|
||||||
|
prompt = dgettext("errors", "Tag could not be removed")
|
||||||
|
socket |> put_flash(:error, prompt)
|
||||||
|
|
||||||
|
%{name: tag_name} = tag ->
|
||||||
|
_container_tag = Containers.remove_tag!(container, tag, current_user)
|
||||||
|
container = container |> Repo.preload(:tags, force: true)
|
||||||
|
prompt = dgettext("prompts", "%{name} removed successfully", name: tag_name)
|
||||||
|
socket |> put_flash(:info, prompt) |> assign(container: container)
|
||||||
|
end
|
||||||
|
|
||||||
|
{:noreply, socket}
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec tag_options([Tag.t()], Container.t()) :: [{String.t(), Tag.id()}]
|
||||||
|
defp tag_options(tags, %Container{tags: container_tags}) do
|
||||||
|
container_tags_map = container_tags |> Enum.map(fn %{id: id} -> id end) |> MapSet.new()
|
||||||
|
|
||||||
|
tags
|
||||||
|
|> Enum.reject(fn %{id: id} -> container_tags_map |> MapSet.member?(id) end)
|
||||||
|
|> Enum.map(fn %{id: id, name: name} -> {name, id} end)
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,56 @@
|
|||||||
|
<div class="flex flex-col justify-center items-center text-center space-y-8">
|
||||||
|
<h2 class="title text-xl text-primary-600">
|
||||||
|
<%= @title %>
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<div class="flex flex-wrap justify-center items-center">
|
||||||
|
<%= for tag <- @container.tags do %>
|
||||||
|
<%= link to: "#",
|
||||||
|
class: "mx-2 my-1 px-4 py-2 rounded-lg title text-xl",
|
||||||
|
style: "color: #{tag.text_color}; background-color: #{tag.bg_color}",
|
||||||
|
phx_click: "delete",
|
||||||
|
phx_value_tag_id: tag.id,
|
||||||
|
phx_target: @myself,
|
||||||
|
data: [
|
||||||
|
confirm:
|
||||||
|
dgettext(
|
||||||
|
"prompts",
|
||||||
|
"Are you sure you want to remove the %{tag_name} tag from %{container_name}?",
|
||||||
|
tag_name: tag.name,
|
||||||
|
container_name: @container.name
|
||||||
|
)
|
||||||
|
] do %>
|
||||||
|
<%= tag.name %>
|
||||||
|
<i class="fa-fw fa-sm fas fa-trash"></i>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<%= if @container.tags |> Enum.empty?() do %>
|
||||||
|
<h2 class="title text-xl text-primary-600">
|
||||||
|
<%= gettext("No tags") %>
|
||||||
|
<%= display_emoji("😔") %>
|
||||||
|
</h2>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<%= unless tag_options(@tags, @container) |> Enum.empty?() do %>
|
||||||
|
<hr class="hr">
|
||||||
|
|
||||||
|
<.form
|
||||||
|
let={f}
|
||||||
|
for={:tag}
|
||||||
|
id="add-tag-to-container-form"
|
||||||
|
class="flex flex-col sm:grid sm:grid-cols-3 sm:gap-4 justify-center items-center"
|
||||||
|
phx-target={@myself}
|
||||||
|
phx-submit="save"
|
||||||
|
>
|
||||||
|
<%= select(f, :tag_id, tag_options(@tags, @container), class: "text-center col-span-2 input input-primary") %>
|
||||||
|
<%= error_tag(f, :tag_id, "col-span-3 text-center") %>
|
||||||
|
|
||||||
|
<%= submit(dgettext("actions", "Add"),
|
||||||
|
class: "mx-auto btn btn-primary",
|
||||||
|
phx_disable_with: dgettext("prompts", "Adding...")
|
||||||
|
) %>
|
||||||
|
</.form>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
@ -5,13 +5,13 @@ defmodule CanneryWeb.ContainerLive.Index do
|
|||||||
|
|
||||||
use CanneryWeb, :live_view
|
use CanneryWeb, :live_view
|
||||||
import CanneryWeb.Components.ContainerCard
|
import CanneryWeb.Components.ContainerCard
|
||||||
alias Cannery.{Containers, Containers.Container}
|
alias Cannery.{Containers, Containers.Container, Repo}
|
||||||
alias CanneryWeb.Endpoint
|
alias CanneryWeb.Endpoint
|
||||||
alias Ecto.Changeset
|
alias Ecto.Changeset
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def mount(_params, session, socket) do
|
def mount(_params, session, socket) do
|
||||||
{:ok, socket |> assign_defaults(session) |> display_containers()}
|
{:ok, socket |> assign_defaults(session)}
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
@ -20,9 +20,13 @@ defmodule CanneryWeb.ContainerLive.Index do
|
|||||||
end
|
end
|
||||||
|
|
||||||
defp apply_action(%{assigns: %{current_user: current_user}} = socket, :edit, %{"id" => id}) do
|
defp apply_action(%{assigns: %{current_user: current_user}} = socket, :edit, %{"id" => id}) do
|
||||||
|
%{name: container_name} =
|
||||||
|
container =
|
||||||
|
Containers.get_container!(id, current_user)
|
||||||
|
|> Repo.preload([:tags, :ammo_groups], force: true)
|
||||||
|
|
||||||
socket
|
socket
|
||||||
|> assign(:page_title, gettext("Edit Container"))
|
|> assign(page_title: gettext("Edit %{name}", name: container_name), container: container)
|
||||||
|> assign(:container, Containers.get_container!(id, current_user))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
defp apply_action(socket, :new, _params) do
|
defp apply_action(socket, :new, _params) do
|
||||||
@ -30,7 +34,19 @@ defmodule CanneryWeb.ContainerLive.Index do
|
|||||||
end
|
end
|
||||||
|
|
||||||
defp apply_action(socket, :index, _params) do
|
defp apply_action(socket, :index, _params) do
|
||||||
socket |> assign(:page_title, gettext("Listing Containers")) |> assign(:container, nil)
|
socket
|
||||||
|
|> assign(:page_title, gettext("Listing Containers"))
|
||||||
|
|> assign(:container, nil)
|
||||||
|
|> display_containers()
|
||||||
|
end
|
||||||
|
|
||||||
|
defp apply_action(%{assigns: %{current_user: current_user}} = socket, :edit_tags, %{"id" => id}) do
|
||||||
|
%{name: container_name} =
|
||||||
|
container =
|
||||||
|
Containers.get_container!(id, current_user) |> Repo.preload([:tags, :ammo_groups])
|
||||||
|
|
||||||
|
page_title = gettext("Edit %{name} tags", name: container_name)
|
||||||
|
socket |> assign(page_title: page_title, container: container)
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
@ -70,6 +86,9 @@ defmodule CanneryWeb.ContainerLive.Index do
|
|||||||
end
|
end
|
||||||
|
|
||||||
defp display_containers(%{assigns: %{current_user: current_user}} = socket) do
|
defp display_containers(%{assigns: %{current_user: current_user}} = socket) do
|
||||||
socket |> assign(containers: Containers.list_containers(current_user))
|
containers =
|
||||||
|
Containers.list_containers(current_user) |> Repo.preload([:tags, :ammo_groups], force: true)
|
||||||
|
|
||||||
|
socket |> assign(containers: containers)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -23,6 +23,15 @@
|
|||||||
<div class="flex flex-row flex-wrap justify-center items-center">
|
<div class="flex flex-row flex-wrap justify-center items-center">
|
||||||
<%= for container <- @containers do %>
|
<%= for container <- @containers do %>
|
||||||
<.container_card container={container}>
|
<.container_card container={container}>
|
||||||
|
<:tag_actions>
|
||||||
|
<div class="mx-4 my-2">
|
||||||
|
<%= live_patch to: Routes.container_index_path(Endpoint, :edit_tags, container),
|
||||||
|
class: "text-primary-600 link" do %>
|
||||||
|
<i class="fa-fw fa-lg fas fa-tags"></i>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</:tag_actions>
|
||||||
|
|
||||||
<%= live_patch to: Routes.container_index_path(Endpoint, :edit, container),
|
<%= live_patch to: Routes.container_index_path(Endpoint, :edit, container),
|
||||||
class: "text-primary-600 link",
|
class: "text-primary-600 link",
|
||||||
data: [qa: "edit-#{container.id}"] do %>
|
data: [qa: "edit-#{container.id}"] do %>
|
||||||
@ -58,3 +67,16 @@
|
|||||||
/>
|
/>
|
||||||
</.modal>
|
</.modal>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
<%= if @live_action == :edit_tags do %>
|
||||||
|
<.modal return_to={Routes.container_index_path(Endpoint, :index)}>
|
||||||
|
<.live_component
|
||||||
|
module={CanneryWeb.ContainerLive.EditTagsComponent}
|
||||||
|
id={@container.id}
|
||||||
|
title={@page_title}
|
||||||
|
action={@live_action}
|
||||||
|
container={@container}
|
||||||
|
current_user={@current_user}
|
||||||
|
/>
|
||||||
|
</.modal>
|
||||||
|
<% end %>
|
||||||
|
@ -19,10 +19,9 @@ defmodule CanneryWeb.ContainerLive.Show do
|
|||||||
def handle_params(
|
def handle_params(
|
||||||
%{"id" => id},
|
%{"id" => id},
|
||||||
_,
|
_,
|
||||||
%{assigns: %{current_user: current_user, live_action: live_action}} = socket
|
%{assigns: %{current_user: current_user}} = socket
|
||||||
) do
|
) do
|
||||||
{:noreply,
|
{:noreply, socket |> render_container(id, current_user)}
|
||||||
socket |> assign(page_title: page_title(live_action)) |> render_container(id, current_user)}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
@ -85,16 +84,19 @@ defmodule CanneryWeb.ContainerLive.Show do
|
|||||||
{:noreply, socket}
|
{:noreply, socket}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp page_title(:show), do: gettext("Show Container")
|
|
||||||
defp page_title(:edit), do: gettext("Edit Container")
|
|
||||||
defp page_title(:add_tag), do: gettext("Add Tag to Container")
|
|
||||||
|
|
||||||
@spec render_container(Socket.t(), Container.id(), User.t()) :: Socket.t()
|
@spec render_container(Socket.t(), Container.id(), User.t()) :: Socket.t()
|
||||||
defp render_container(socket, id, current_user) do
|
defp render_container(%{assigns: %{live_action: live_action}} = socket, id, current_user) do
|
||||||
container =
|
%{name: container_name} = container =
|
||||||
Containers.get_container!(id, current_user)
|
Containers.get_container!(id, current_user)
|
||||||
|> Repo.preload([:ammo_groups, :tags], force: true)
|
|> Repo.preload([:ammo_groups, :tags], force: true)
|
||||||
|
|
||||||
socket |> assign(container: container)
|
page_title =
|
||||||
|
case live_action do
|
||||||
|
:show -> gettext("Show %{name}", name: container_name)
|
||||||
|
:edit -> gettext("Edit %{name}", name: container_name)
|
||||||
|
:edit_tags -> gettext("Edit %{name} tags", name: container_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
socket |> assign(container: container, page_title: page_title)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -51,34 +51,23 @@
|
|||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<%= live_patch(dgettext("actions", "Why not add one?"),
|
<%= live_patch(dgettext("actions", "Why not add one?"),
|
||||||
to: Routes.container_show_path(Endpoint, :add_tag, @container),
|
to: Routes.container_show_path(Endpoint, :edit_tags, @container),
|
||||||
class: "btn btn-primary"
|
class: "btn btn-primary"
|
||||||
) %>
|
) %>
|
||||||
</div>
|
</div>
|
||||||
<% else %>
|
<% else %>
|
||||||
<h2 class="mb-4 title text-xl text-primary-600">
|
<div class="flex flex-wrap justify-center items-center">
|
||||||
<%= gettext("Tags") %>
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
<%= for tag <- @container.tags do %>
|
<%= for tag <- @container.tags do %>
|
||||||
<.tag_card tag={tag}>
|
<.simple_tag_card tag={tag} />
|
||||||
<%= link to: "#",
|
|
||||||
class: "text-primary-600 link",
|
|
||||||
phx_click: "delete_tag",
|
|
||||||
phx_value_tag_id: tag.id,
|
|
||||||
data: [
|
|
||||||
confirm:
|
|
||||||
dgettext(
|
|
||||||
"prompts",
|
|
||||||
"Are you sure you want to remove the %{tag_name} tag from %{container_name}?",
|
|
||||||
tag_name: tag.name,
|
|
||||||
container_name: @container.name
|
|
||||||
)
|
|
||||||
] do %>
|
|
||||||
<i class="fa-fw fa-lg fas fa-trash"></i>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
</.tag_card>
|
|
||||||
|
<div class="mx-4 my-2">
|
||||||
|
<%= live_patch to: Routes.container_show_path(Endpoint, :edit_tags, @container),
|
||||||
|
class: "text-primary-600 link" do %>
|
||||||
|
<i class="fa-fw fa-lg fas fa-tags"></i>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<hr class="mb-4 hr" />
|
<hr class="mb-4 hr" />
|
||||||
@ -87,9 +76,11 @@
|
|||||||
<%= if @container.ammo_groups |> Enum.empty?() do %>
|
<%= if @container.ammo_groups |> Enum.empty?() do %>
|
||||||
<%= gettext("No ammo groups in this container") %>
|
<%= gettext("No ammo groups in this container") %>
|
||||||
<% else %>
|
<% else %>
|
||||||
|
<div class="flex flex-wrap justify-center items-center">
|
||||||
<%= for ammo_group <- @container.ammo_groups do %>
|
<%= for ammo_group <- @container.ammo_groups do %>
|
||||||
<.ammo_group_card ammo_group={ammo_group} />
|
<.ammo_group_card ammo_group={ammo_group} />
|
||||||
<% end %>
|
<% end %>
|
||||||
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@ -108,10 +99,10 @@
|
|||||||
</.modal>
|
</.modal>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%= if @live_action == :add_tag do %>
|
<%= if @live_action == :edit_tags do %>
|
||||||
<.modal return_to={Routes.container_show_path(Endpoint, :show, @container)}>
|
<.modal return_to={Routes.container_show_path(Endpoint, :show, @container)}>
|
||||||
<.live_component
|
<.live_component
|
||||||
module={CanneryWeb.ContainerLive.AddTagComponent}
|
module={CanneryWeb.ContainerLive.EditTagsComponent}
|
||||||
id={@container.id}
|
id={@container.id}
|
||||||
title={@page_title}
|
title={@page_title}
|
||||||
action={@live_action}
|
action={@live_action}
|
||||||
|
@ -124,7 +124,7 @@ defmodule CanneryWeb.HomeLive do
|
|||||||
<li class="flex flex-row justify-center space-x-2">
|
<li class="flex flex-row justify-center space-x-2">
|
||||||
<b>Version:</b>
|
<b>Version:</b>
|
||||||
<p>
|
<p>
|
||||||
0.1.0
|
0.2.0
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -64,10 +64,11 @@ defmodule CanneryWeb.Router do
|
|||||||
live "/containers", ContainerLive.Index, :index
|
live "/containers", ContainerLive.Index, :index
|
||||||
live "/containers/new", ContainerLive.Index, :new
|
live "/containers/new", ContainerLive.Index, :new
|
||||||
live "/containers/:id/edit", ContainerLive.Index, :edit
|
live "/containers/:id/edit", ContainerLive.Index, :edit
|
||||||
|
live "/containers/:id/edit_tags", ContainerLive.Index, :edit_tags
|
||||||
|
|
||||||
live "/containers/:id", ContainerLive.Show, :show
|
live "/containers/:id", ContainerLive.Show, :show
|
||||||
live "/containers/:id/show/edit", ContainerLive.Show, :edit
|
live "/containers/:id/show/edit", ContainerLive.Show, :edit
|
||||||
live "/containers/:id/show/add_tag", ContainerLive.Show, :add_tag
|
live "/containers/:id/show/edit_tags", ContainerLive.Show, :edit_tags
|
||||||
|
|
||||||
live "/ammo_groups", AmmoGroupLive.Index, :index
|
live "/ammo_groups", AmmoGroupLive.Index, :index
|
||||||
live "/ammo_groups/new", AmmoGroupLive.Index, :new
|
live "/ammo_groups/new", AmmoGroupLive.Index, :new
|
||||||
|
2
mix.exs
2
mix.exs
@ -4,7 +4,7 @@ defmodule Cannery.MixProject do
|
|||||||
def project do
|
def project do
|
||||||
[
|
[
|
||||||
app: :cannery,
|
app: :cannery,
|
||||||
version: "0.1.0",
|
version: "0.2.0",
|
||||||
elixir: "~> 1.12",
|
elixir: "~> 1.12",
|
||||||
elixirc_paths: elixirc_paths(Mix.env()),
|
elixirc_paths: elixirc_paths(Mix.env()),
|
||||||
compilers: [:gettext] ++ Mix.compilers(),
|
compilers: [:gettext] ++ Mix.compilers(),
|
||||||
|
Loading…
Reference in New Issue
Block a user