Masu.Live (Masu v0.1.0)

Copy Markdown View Source

Live rows: a grid that follows a PubSub topic, and shows the rows that change on it as they change.

<.data_grid id="orders" source={Order} repo={Repo} live={{MyApp.PubSub, "orders"}}>

Where the rows change, broadcast them:

{:ok, order} = Repo.update(changeset)
Masu.Live.broadcast_upsert(MyApp.PubSub, "orders", order)

Repo.delete!(order)
Masu.Live.broadcast_delete(MyApp.PubSub, "orders", order)

The grid takes the change into the rows of its query, with the person's order, filters and search, changes its count, and the browser shows the new rows in the place the person reads, each changed row with a short highlight. A grid of an Ecto source asks its query again; a grid of a list puts the row in the list (by its id), or takes it out.

Changes that come together, as from a batch of updates, make one new set of rows: the grid takes every change that waits in the LiveView's mailbox at once.

The hook

The LiveView process subscribes to the topic, and its handle_info receives the changes: this on_mount hook takes them, so the LiveView needs no clause of its own. Add it to the LiveView, or to its live_session:

on_mount Masu.Live

live_session :default, on_mount: [Masu.Live] do

A grid with live in a LiveView without the hook raises, saying so.

A list and its LiveView

A grid of a list keeps the changes in its own copy of the list. The LiveView's assign does not change: give the grid new rows (which replace its copy) or broadcast changes, not both.

Summary

Types

A change to the rows of a topic.

Functions

Broadcasts a row that was deleted, given as the row or its id: a grid that follows the topic takes it out.

Broadcasts a row that was inserted or changed: a grid that follows the topic shows it, in the place of its query.

The export of the grid grid of this LiveView (Masu.Export): its rows as they are now (the person's order, filters and search), with the columns that show. Call it in the LiveView; write it anywhere.

The rows selected in the grid grid of this LiveView (selectable): {:ids, ids}, or, when the person selected every row of the query, {:query, query} for an Ecto source (an Ecto.Query of the rows, with the person's filters and search, less the rows they took out of it) and {:ids, ids} of every such row for a list.

Types

change()

@type change() :: {:upsert, term()} | {:delete, term()}

A change to the rows of a topic.

Functions

broadcast_delete(pubsub, topic, row_or_id)

@spec broadcast_delete(atom(), String.t(), term()) :: :ok | {:error, term()}

Broadcasts a row that was deleted, given as the row or its id: a grid that follows the topic takes it out.

broadcast_upsert(pubsub, topic, row)

@spec broadcast_upsert(atom(), String.t(), term()) :: :ok | {:error, term()}

Broadcasts a row that was inserted or changed: a grid that follows the topic shows it, in the place of its query.

export(grid)

@spec export(String.t()) :: Masu.Export.t()

The export of the grid grid of this LiveView (Masu.Export): its rows as they are now (the person's order, filters and search), with the columns that show. Call it in the LiveView; write it anywhere.

selected(grid)

@spec selected(String.t()) :: {:ids, [term()]} | {:query, term()}

The rows selected in the grid grid of this LiveView (selectable): {:ids, ids}, or, when the person selected every row of the query, {:query, query} for an Ecto source (an Ecto.Query of the rows, with the person's filters and search, less the rows they took out of it) and {:ids, ids} of every such row for a list.

def handle_event("archive", _params, socket) do
  case Masu.Live.selected("orders") do
    {:ids, ids} -> Orders.archive(ids)
    {:query, query} -> Repo.update_all(query, set: [archived: true])
  end

  {:noreply, socket}
end