PhoenixKitWarehouse. Web. Components. WarehouseBrowser
(PhoenixKitWarehouse v0.4.0)
Copy Markdown
View Source
Warehouse-specific catalogue tree components.
Stateless function components driven by assigns from the parent LiveView:
stock_tree/1— read-only lazy tree annotated with stock quantity and value.count_sheet/1— editable table of inventory document lines grouped by catalogue → category, with conditional price/sum columns.
Adding new positions to a document (internal orders, stocktakes, transfers)
goes through PhoenixKitCatalogue.Web.Components.ItemSelectorModal directly
— not through a component here. The picker that used to live in this module
(add_picker/1) only ever added lines; it never touched a stock-specific
field, so nothing warehouse-specific was lost by routing that action through
the catalogue's own selector instead.
Tree toggle state (expanded_catalogues, expanded_categories,
loaded_categories, loaded_items) lives in the parent LV. These components
are stateless — they only render.
Summary
Functions
Editable table of inventory document lines grouped by catalogue → category.
Returns the display name of a catalogue / category / item record in the
given UI locale, reading translations from the multilang data JSONB via
PhoenixKitCatalogue.Catalogue.get_translation/2. Falls back to the
embedded primary translation, then to the denormalized name column.
Returns nil for nil records.
Stateless modal component for selecting source documents to import into a warehouse document.
Read-only stock sheet grouped by catalogue → category.
Read-only lazy catalogue tree annotated with stock quantity and total value.
Strips a configurable catalogue-name prefix (case-insensitive), along with any single separating space. Returns the original name if the prefix isn't present, or if stripping would yield an empty string.
Short localized label for a catalogue item unit of measure. Ported from
Andi.Catalogues.unit_label/1 verbatim.
Functions
Editable table of inventory document lines grouped by catalogue → category.
Each catalogue group is rendered as a DaisyUI collapsible section (open by
default). Category sub-headers are preserved; each category section ends with
a <tfoot> row showing the quantity subtotal. A quantity subtotal badge is
also shown in the catalogue-level collapsible header.
Columns:
- Name / SKU
- Unit
- Current stock (read-only, from
stock_map) - Counted (number input, event
set_counted) - Unit price (event
set_price) — only whentrack_value - Sum (event
set_sum) — only whentrack_value - Remove button (event
remove_line)
The names map provides localized display names keyed by UUID:
- item UUID → item name
- catalogue UUID → catalogue display name
- category UUID → category name
Line snapshot names (line["name"]) are used as fallback when the UUID
is not in the map.
Price/sum columns are hidden entirely when track_value is false.
Attributes
lines(:list) (required)track_value(:boolean) (required)names(:map) (required)stock_map(:map) (required)locale(:string) (required)editable(:boolean) - Defaults totrue.
Returns the display name of a catalogue / category / item record in the
given UI locale, reading translations from the multilang data JSONB via
PhoenixKitCatalogue.Catalogue.get_translation/2. Falls back to the
embedded primary translation, then to the denormalized name column.
Returns nil for nil records.
Ported from Andi.Catalogues.localized_name/2 — that function does not
exist on PhoenixKitCatalogue.Catalogue itself (confirmed, matching
Plan 3's identical finding for Inventories), so this is real ported
logic, not a call-through. Unlike the original, locale is used exactly
as given — the original's Andi.Locales.entity_locale/1/current_locale/0
normalization is Andi-specific and dropped; callers pass an
already-resolved locale string (see this plan's Global Constraints on
Andi.Locales.sync_from_phoenix_kit/0).
Stateless modal component for selecting source documents to import into a warehouse document.
Attrs
id— explicit modal id (string, required). Pass a stable per-form id to avoid collision when multiple modals share the same page.show— controls visibility (boolean, required).title— modal header title string (required).on_close— phx event name sent on cancel / backdrop click (string, required).candidates— list of%{uuid, label, label_prefix}maps to display (label_prefix is optional). The parent LiveView builds this list from DB queries inhandle_event/3for"source_picker_search".selected_uuids—MapSet(or list) of already-selected UUIDs; drives the checkbox state per row (required).search_query— current value of the search input, echoed into the field on re-render (default"").
Parent events to implement
The component fires these fixed phx event names; the parent LiveView MUST
implement handle_event/3 for each:
"source_picker_search"— fired on phx-change of the search form. Params:%{"query" => string}. The parent should re-query candidates and assign them."source_picker_toggle"— fired on phx-click of a candidate row. Params:%{"uuid" => binary}. The parent should toggle the UUID in/out ofselected_uuids."source_picker_select_all"— fired on phx-click of the "Select all" toggle. No extra phx-values. The parent should select every UUID currently incandidateswhen not all are selected yet, or clear the selection when they already all are."source_picker_confirm"— fired on the "Import (N)" primary button. No extra phx-values. The parent reads its ownselected_uuidsassign, runs the import logic, and then clears the modal.
The on_close event is also a parent-side event (cancel / backdrop close).
Attributes
id(:string) (required)show(:boolean) (required)title(:string) (required)on_close(:string) (required)candidates(:list) - Defaults to[].selected_uuids(:any) - Defaults to[].search_query(:string) - Defaults to"".
Read-only stock sheet grouped by catalogue → category.
Accepts a flat list of %{item, quantity, unit_value} maps where item
has :catalogue and :category preloaded. Groups are rendered as DaisyUI
collapsible sections (open by default) with a quantity subtotal badge in
the catalogue header and a per-category <tfoot> subtotal row.
Columns: Item (name + SKU) / Unit / In stock (qty) / Total value.
Entries may optionally carry a :below_min? boolean (§5 — deficit
tracking, set by Web.StockLive.build_stock_items/1) — when true, a small
warning icon renders next to the item name. Missing/false is the default
(Map.get(entry, :below_min?, false)), so callers that don't track
deficits can keep passing the plain %{item, quantity, unit_value} shape.
Attributes
stock_items(:list) (required)locale(:string) (required)
Read-only lazy catalogue tree annotated with stock quantity and total value.
Each item row shows:
- Quantity in stock (with unit label)
- Total value (
quantity * unit_value) — only whenunit_valueis known; otherwise shows a—placeholder.
Toggle events (toggle_catalogue / toggle_category) are sent to the
parent LiveView which updates expanded_* and loaded_* assigns.
Attributes
catalogue_summaries(:list) (required)expanded_catalogues(:any) (required)expanded_categories(:any) (required)loaded_categories(:map) (required)loaded_items(:map) (required)locale(:string) (required)stock_map(:map) (required)
Strips a configurable catalogue-name prefix (case-insensitive), along with any single separating space. Returns the original name if the prefix isn't present, or if stripping would yield an empty string.
Ported from Andi.Catalogues.strip_prefix/1. The original reads
Application.get_env(:andi, :catalogue_prefix, "ANDI") — Andi-specific
config the package cannot reference. This reads
Application.get_env(:phoenix_kit_warehouse, :catalogue_prefix, "")
instead, defaulting to an empty string (no-op — every catalogue name
passes through unchanged) rather than a hardcoded brand string, so the
package behaves sensibly out of the box for a fresh host with no
catalogue-naming convention at all. A host that does use a shared naming
prefix opts in via config.
Short localized label for a catalogue item unit of measure. Ported from
Andi.Catalogues.unit_label/1 verbatim.