PhoenixKitLocations.Web.Components.SpaceTree (PhoenixKitLocations v0.3.0)

Copy Markdown View Source

Recursive tree of a Location's Space hierarchy (floors, rooms, zones, sections, aisles, shelves) — an adaptation of PhoenixKitWeb.Components.FolderExplorer.folder_tree_node/1 for PhoenixKitLocations.Spaces.list_tree/1 nodes. Simplified relative to that model: no desktop-only fixed-width sidebar and no drag/drop or connector-line CSS — a single full-width column.

Node shape

Spaces.list_tree/1 returns a plain list of %Space{} structs — each node carries its children directly under the schema's own :children association key (Map.put(space, :children, ...)), not wrapped in a %{space: ..., children: ...} envelope the way FolderExplorer's %{folder: ..., children: ...} nodes are. Every field on a node is read straight off the struct: node.kind, node.uuid, node.name, node.status, node.children — never node.space.kind.

Ownership model

Pure presentation. The consumer owns all state (expanded MapSet, selected_uuid, renaming_uuid/renaming_text) — every interactive control fires back via phx-target={@myself}. Pass myself={nil} when the consumer is a plain LiveView rather than a LiveComponent; phx-target is then simply omitted, routing the event to the LiveView itself.

Reorder (▲/▼) and rename are the only actions this component treats as "immediate" — they fire their event straight away. Everything else (creating a space, editing its other fields) is left to a form panel owned by the consumer. delete_space is deliberately not immediate either — no data-confirm here, since a hard delete cascades to the whole subtree: the event just asks the consumer to open its own confirmation modal (with the descendant count), which is the only place the actual delete is triggered from.

Consumers implement:

toggle_space_node, select_space,
start_rename_space, rename_space_input, rename_space, cancel_rename_space,
move_space_up, move_space_down, open_add_child,
delete_space (opens a confirmation  does not delete by itself),
open_add_root (the "+ Add root space" button in `space_tree/1`)

Picker mode

show_actions={false} hides the rename/reorder/add-child/delete affordances on every node (and the wrapper's "+ Add root space" button) and leaves only click-to-select + expand/collapse — the shape PlacePicker (v0.5) needs to reuse this same tree read-only.

Usage

<.space_tree
  tree={@tree}
  expanded={@expanded}
  selected_uuid={@selected_uuid}
  myself={nil}
/>

Summary

Functions

space_tree(assigns)

Attributes

  • tree (:list) (required) - Root-level nodes from Spaces.list_tree/1.
  • expanded (:any) (required) - MapSet of expanded node UUIDs.
  • selected_uuid (:string) - Defaults to nil.
  • renaming_uuid (:string) - Defaults to nil.
  • renaming_text (:string) - Defaults to "".
  • myself (:any) - LiveComponent CID, or nil when the consumer is a plain LiveView. Defaults to nil.
  • on_select (:string) - Defaults to "select_space".
  • on_toggle (:string) - Defaults to "toggle_space_node".
  • on_add_root (:string) - Defaults to "open_add_root".
  • show_actions (:boolean) - false switches every node into picker/read-only mode (select + expand only). Defaults to true.

space_tree_node(assigns)

Attributes

  • node (:map) (required) - A %Space{} struct with a nested :children list (see moduledoc).
  • expanded (:any) (required)
  • selected_uuid (:string) - Defaults to nil.
  • renaming_uuid (:string) - Defaults to nil.
  • renaming_text (:string) - Defaults to "".
  • depth (:integer) - Defaults to 0.
  • is_first (:boolean) - Hides the move-up button when true. Defaults to true.
  • is_last (:boolean) - Hides the move-down button when true. Defaults to true.
  • myself (:any) - Defaults to nil.
  • on_select (:string) - Defaults to "select_space".
  • on_toggle (:string) - Defaults to "toggle_space_node".
  • show_actions (:boolean) - false hides pencil/reorder/add-child/delete — click-to-select + expand only. Defaults to true.