PhoenixKitWarehouse.Web.Components.WarehouseBrowser (PhoenixKitWarehouse v0.1.0)

Copy Markdown View Source

Warehouse-specific catalogue tree components.

Three stateless function components driven by assigns from the parent LiveView:

  • stock_tree/1 — read-only lazy tree annotated with stock quantity and value.
  • add_picker/1 — lazy tree with search and an Add action per item, for adding positions to an inventory document.
  • count_sheet/1 — editable table of inventory document lines grouped by catalogue → category, with conditional price/sum columns.

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

Lazy catalogue tree with search input and an Add button per item.

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

add_picker(assigns)

Lazy catalogue tree with search input and an Add button per item.

Used in the inventory form to add catalogue items not yet in the count sheet (goods receipt). Items whose UUID is in present_item_uuids are shown as disabled (already in the sheet). Re-adding a previously removed line is allowed — callers should recompute present_item_uuids from the live lines after every add/remove.

The add button fires a phx-click with the event named by add_event (default "add_position") and phx-value-item_uuid.

Attributes

  • catalogue_summaries (:list) (required)
  • expanded_catalogues (:any) (required)
  • expanded_categories (:any) (required)
  • loaded_categories (:map) (required)
  • loaded_items (:map) (required)
  • locale (:string) (required)
  • present_item_uuids (:any) - Defaults to MapSet.new([]).
  • item_search_query (:string) - Defaults to "".
  • item_search_results (:any) - Defaults to nil.
  • add_event (:string) - Defaults to "add_position".
  • search_mode (:atom) - Defaults to :list.

count_sheet(assigns)

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 when track_value
  • Sum (event set_sum) — only when track_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 to true.

localized_name(record, locale)

@spec localized_name(map() | struct() | nil, String.t() | nil) :: String.t() | nil

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).

source_picker(assigns)

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 in handle_event/3 for "source_picker_search".
  • selected_uuidsMapSet (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 of selected_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 in candidates when 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 own selected_uuids assign, 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 "".

stock_sheet(assigns)

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.

Attributes

  • stock_items (:list) (required)
  • locale (:string) (required)

stock_tree(assigns)

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 when unit_value is 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)

strip_prefix(name)

@spec strip_prefix(String.t() | nil) :: String.t() | nil

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.

unit_label(other)

@spec unit_label(String.t() | nil) :: String.t()

Short localized label for a catalogue item unit of measure. Ported from Andi.Catalogues.unit_label/1 verbatim.