# `Narabe.Live`
[🔗](https://github.com/hattoriai/narabe/blob/v0.1.0/lib/narabe/live.ex#L1)

Helpers for the LiveView of a list, a tree or a board.

    def handle_event("move", params, socket) do
      move = Narabe.Move.parse!(params, Task)
      result = Narabe.Ecto.move(Repo, Task, move)

      socket =
        case result do
          {:ok, moved} -> Narabe.Live.stream_move(socket, :tasks, moved, move)
          {:error, _} -> socket
        end

      {:reply, Narabe.Live.reply(result), socket}
    end

The browser has moved the items already; the reply says whether it may
keep them there (`%{ok: true}`) or puts them back (`%{error: ...}`).

# `expand`

```elixir
@spec expand(Phoenix.LiveView.Socket.t(), String.t(), term() | [term()], boolean()) ::
  Phoenix.LiveView.Socket.t()
```

Opens (or closes) rows of a tree from the server: `ids`, or one id.
Rows whose children are not loaded ask for them (`on_expand`).

# `reply`

```elixir
@spec reply(term()) :: map()
```

The reply to a move event, from what `Narabe.Ecto.move/4` (or a
transaction, or the app's own code) returned.

## Examples

    iex> Narabe.Live.reply({:ok, []})
    %{ok: true}

    iex> Narabe.Live.reply({:error, :too_deep})
    %{error: "too_deep"}

    iex> Narabe.Live.reply({:error, :move, :not_found, %{}})
    %{error: "not_found"}

    iex> Narabe.Live.reply({:error, "Archived boards don't change"})
    %{error: "refused", message: "Archived boards don't change"}

# `reveal`

```elixir
@spec reveal(Phoenix.LiveView.Socket.t(), String.t(), term()) ::
  Phoenix.LiveView.Socket.t()
```

Opens a row's ancestors, scrolls to it and focuses it.

# `select`

```elixir
@spec select(Phoenix.LiveView.Socket.t(), String.t(), [term()]) ::
  Phoenix.LiveView.Socket.t()
```

Selects rows from the server (no `on_select` event follows).

# `stream_move`

```elixir
@spec stream_move(
  Phoenix.LiveView.Socket.t(),
  atom() | String.t(),
  term(),
  Narabe.Move.t()
) ::
  Phoenix.LiveView.Socket.t()
```

Puts a moved item in its new place in a stream, for the other viewers
of a list (the one who moved it sees it there already): it is inserted
again at its index among the stream's items, as the move says.

Give the moved items (the rows `Narabe.Ecto.move/4` returned), or one;
several go one after the other.

A board's columns are each a stream of their own: delete the card from
the old column's stream and insert it in the new one's.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
