refactor(elixir): hierarchical refactor
to extract common code patterns from category/storage location systems
This commit is contained in:
@@ -2,7 +2,7 @@ defmodule ComponentsElixirWeb.ComponentsLive do
|
||||
use ComponentsElixirWeb, :live_view
|
||||
|
||||
alias ComponentsElixir.{Inventory, Auth}
|
||||
alias ComponentsElixir.Inventory.Component
|
||||
alias ComponentsElixir.Inventory.{Component, Category, StorageLocation, Hierarchical}
|
||||
|
||||
@items_per_page 20
|
||||
|
||||
@@ -430,31 +430,15 @@ defmodule ComponentsElixirWeb.ComponentsLive do
|
||||
end
|
||||
|
||||
defp category_options(categories) do
|
||||
[{"Select a category", nil}] ++
|
||||
Enum.map(categories, fn category ->
|
||||
{category.name, category.id}
|
||||
end)
|
||||
Hierarchical.select_options(categories, &(&1.parent), "Select a category")
|
||||
end
|
||||
|
||||
defp storage_location_display_name(location) do
|
||||
# Use the computed path from Inventory context for full hierarchy, or fall back to location.path
|
||||
path = Inventory.compute_storage_location_path(location) || location.path
|
||||
|
||||
if path do
|
||||
# Convert path from "Shelf A/Drawer 2/Box 1" to "Shelf A > Drawer 2 > Box 1"
|
||||
path
|
||||
|> String.split("/")
|
||||
|> Enum.join(" > ")
|
||||
else
|
||||
location.name
|
||||
end
|
||||
StorageLocation.full_path(location)
|
||||
end
|
||||
|
||||
defp storage_location_options(storage_locations) do
|
||||
[{"No storage location", nil}] ++
|
||||
Enum.map(storage_locations, fn location ->
|
||||
{storage_location_display_name(location), location.id}
|
||||
end)
|
||||
Hierarchical.select_options(storage_locations, &(&1.parent), "No storage location")
|
||||
end
|
||||
|
||||
@impl true
|
||||
@@ -503,7 +487,7 @@ defmodule ComponentsElixirWeb.ComponentsLive do
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Filters -->
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
|
||||
<div class="flex flex-col sm:flex-row gap-4">
|
||||
@@ -525,13 +509,9 @@ defmodule ComponentsElixirWeb.ComponentsLive do
|
||||
class="block w-full px-3 py-2 border border-base-300 rounded-md shadow-sm bg-base-100 text-base-content focus:outline-none focus:ring-primary focus:border-primary sm:text-sm"
|
||||
>
|
||||
<option value="" selected={is_nil(@selected_category)}>All Categories</option>
|
||||
<%= for category <- @categories do %>
|
||||
<option value={category.id} selected={@selected_category == category.id}>
|
||||
<%= if category.parent do %>
|
||||
{category.parent.name} > {category.name}
|
||||
<% else %>
|
||||
{category.name}
|
||||
<% end %>
|
||||
<%= for {category_name, category_id} <- Hierarchical.select_options(@categories, &(&1.parent)) do %>
|
||||
<option value={category_id} selected={@selected_category == category_id}>
|
||||
{category_name}
|
||||
</option>
|
||||
<% end %>
|
||||
</select>
|
||||
@@ -580,7 +560,7 @@ defmodule ComponentsElixirWeb.ComponentsLive do
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Add Component Modal -->
|
||||
<%= if @show_add_form do %>
|
||||
<div class="fixed inset-0 bg-base-content/50 overflow-y-auto h-full w-full z-50">
|
||||
@@ -714,7 +694,7 @@ defmodule ComponentsElixirWeb.ComponentsLive do
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
|
||||
<!-- Edit Component Modal -->
|
||||
<%= if @show_edit_form do %>
|
||||
<div class="fixed inset-0 bg-base-content/50 overflow-y-auto h-full w-full z-50">
|
||||
@@ -858,7 +838,7 @@ defmodule ComponentsElixirWeb.ComponentsLive do
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
|
||||
<!-- Components List -->
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 pb-6">
|
||||
<div class="bg-base-100 shadow overflow-hidden sm:rounded-md">
|
||||
@@ -918,7 +898,7 @@ defmodule ComponentsElixirWeb.ComponentsLive do
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Content area with image and details -->
|
||||
<div class="flex gap-6">
|
||||
<!-- Large Image -->
|
||||
@@ -944,7 +924,7 @@ defmodule ComponentsElixirWeb.ComponentsLive do
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Details -->
|
||||
<div class="flex-1 space-y-4 select-text">
|
||||
<!-- Full Description -->
|
||||
@@ -956,7 +936,7 @@ defmodule ComponentsElixirWeb.ComponentsLive do
|
||||
</p>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
|
||||
<!-- Metadata Grid -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 text-sm">
|
||||
<%= if component.storage_location do %>
|
||||
@@ -1013,7 +993,7 @@ defmodule ComponentsElixirWeb.ComponentsLive do
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Action Buttons -->
|
||||
<div class="flex justify-end items-center space-x-2 pt-4 border-t border-base-300">
|
||||
<button
|
||||
@@ -1098,7 +1078,7 @@ defmodule ComponentsElixirWeb.ComponentsLive do
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Middle row: Description -->
|
||||
<%= if component.description do %>
|
||||
<div class="mt-1">
|
||||
@@ -1107,7 +1087,7 @@ defmodule ComponentsElixirWeb.ComponentsLive do
|
||||
</p>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
|
||||
<!-- Bottom row: Metadata -->
|
||||
<div class="mt-2 grid grid-cols-1 sm:grid-cols-3 gap-x-4 gap-y-1 text-sm text-base-content/60">
|
||||
<%= if component.storage_location do %>
|
||||
@@ -1135,7 +1115,7 @@ defmodule ComponentsElixirWeb.ComponentsLive do
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Keywords row -->
|
||||
<%= if component.keywords do %>
|
||||
<div class="mt-2">
|
||||
@@ -1218,7 +1198,7 @@ defmodule ComponentsElixirWeb.ComponentsLive do
|
||||
>
|
||||
<!-- Background overlay -->
|
||||
<div class="absolute inset-0 bg-black bg-opacity-75"></div>
|
||||
|
||||
|
||||
<!-- Modal content -->
|
||||
<div
|
||||
class="relative bg-base-100 rounded-lg shadow-xl max-w-4xl w-full max-h-full overflow-auto"
|
||||
@@ -1236,7 +1216,7 @@ defmodule ComponentsElixirWeb.ComponentsLive do
|
||||
×
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Content -->
|
||||
<div class="p-6 bg-base-100 rounded-b-lg">
|
||||
<div class="text-center">
|
||||
|
||||
Reference in New Issue
Block a user