Masu.Group (Masu v0.1.0)

Copy Markdown View Source

Rows grouped by the values of columns, with totals.

<.data_grid id="orders" source={Order} repo={Repo} group_by={[:status]}>
  <:col field={:status} type={:enum} />
  <:col field={:customer} />
  <:col field={:total} type={:decimal} aggregate={:sum} />
</.data_grid>

group_by names the columns the rows are grouped by, the first the outermost. Each group is a row of its own, with its value, how many rows it has, and the totals of the columns that have an aggregate (see Masu.Column); it opens on its groups of the next column, or on its rows. A person groups by a column from its header menu, and the grouping is part of their view (Masu.View).

A row of totals of the whole query shows at the bottom of a grid with a column that has an aggregate, grouped or not.

The groups are counted and totalled by the source: an Ecto source with one GROUP BY for each level that shows, and reads the rows of an open group a block at a time, as it reads any rows; a list in the LiveView. So a million rows in forty groups are forty rows until one opens.

Groups sort by their value; sorting by the grouped column turns their order, and sorting by a column with an aggregate sorts them by it. The rows of a group sort as the grid's rows do.

A group row's id is ["masu-group", key, value, ...], its path: it is what Masu.Test.expand/3 takes to open it.

Summary

Types

t()

@type t() :: %Masu.Group{
  aggregates: %{required(String.t()) => term()},
  count: non_neg_integer(),
  key: String.t(),
  path: [{String.t(), term()}],
  value: term()
}