Narabe.Move (Narabe v0.1.0)

Copy Markdown View Source

A move, as a drop sends it: these items (one, or several selected), into this parent (a tree's item, a board's column, or nil for the top level or a plain list), right after one item, or right before another.

%Narabe.Move{ids: [42], parent: 7, after: 12, before: 13, index: 3}

The move says where by ids, not by an index: a screen a moment out of date still means what the person saw ("after Roadmap"), whoever moved what meanwhile. after wins over before; index is a last resort, for a neighbour that is gone.

The browser sends it to the list's on_move event:

def handle_event("moved", params, socket) do
  {:ok, move} = Narabe.Move.parse(params, Card)
  ...
end

Summary

Functions

Applies a move to items in memory, in their order: a list, a board's cards (each with its column in :group), or a tree's items, flat (each with its parent in :group, and tree: true). For apps that keep the order themselves, without Narabe.Ecto, and for tests.

A move from the params of an on_move event, its ids cast to the type of a schema's primary key (or to an Ecto type, :id, :binary_id, :string); the browser sends ids as text.

As parse/2, raising ArgumentError for params that are no move.

The params of a move, as the browser sends them: for Narabe.Test and an agent's tool that moves items as a person would.

Types

id()

@type id() :: term()

t()

@type t() :: %Narabe.Move{
  after: id() | nil,
  before: id() | nil,
  ids: [id()],
  index: non_neg_integer() | nil,
  parent: id() | nil
}

Functions

apply(items, move, opts \\ [])

@spec apply([term()], t(), keyword()) ::
  {:ok, [term()]} | {:error, :not_found | :into_itself}

Applies a move to items in memory, in their order: a list, a board's cards (each with its column in :group), or a tree's items, flat (each with its parent in :group, and tree: true). For apps that keep the order themselves, without Narabe.Ecto, and for tests.

Returns {:ok, items}, the items in their new order with the moved ones' group set, or {:error, reason}: :not_found (an id that is not among the items), or :into_itself (a tree item into itself or under itself).

Options:

  • :id - an item's id: a key or a function (:id).
  • :group - the key of its column or parent (none: one list).
  • :tree - whether :group is a parent among the items.

Examples

iex> items = [%{id: 1}, %{id: 2}, %{id: 3}]
iex> {:ok, moved} = Narabe.Move.apply(items, %Narabe.Move{ids: [1], after: 3})
iex> Enum.map(moved, & &1.id)
[2, 3, 1]

iex> cards = [%{id: 1, col: :todo}, %{id: 2, col: :done}]
iex> {:ok, moved} = Narabe.Move.apply(cards, %Narabe.Move{ids: [1], parent: :done, before: 2}, group: :col)
iex> moved
[%{id: 1, col: :done}, %{id: 2, col: :done}]

parse(params, schema_or_type \\ :string)

@spec parse(map(), module() | atom()) :: {:ok, t()} | {:error, :invalid_move}

A move from the params of an on_move event, its ids cast to the type of a schema's primary key (or to an Ecto type, :id, :binary_id, :string); the browser sends ids as text.

iex> Narabe.Move.parse(%{"v" => 1, "ids" => ["42"], "parent" => "7", "after" => "12", "before" => nil, "index" => 3}, :id)
{:ok, %Narabe.Move{ids: [42], parent: 7, after: 12, before: nil, index: 3}}

iex> Narabe.Move.parse(%{"v" => 1, "ids" => []}, :id)
{:error, :invalid_move}

parse!(params, schema_or_type \\ :string)

@spec parse!(map(), module() | atom()) :: t()

As parse/2, raising ArgumentError for params that are no move.

to_params(move)

@spec to_params(t()) :: map()

The params of a move, as the browser sends them: for Narabe.Test and an agent's tool that moves items as a person would.

iex> Narabe.Move.to_params(%Narabe.Move{ids: [42], after: 12})
%{"v" => 1, "ids" => ["42"], "parent" => nil, "after" => "12", "before" => nil, "index" => nil}