# `Cardbox.Masu`
[🔗](https://github.com/hattoriai/cardbox/blob/v0.1.0/lib/cardbox/masu.ex#L2)

A collection as a Masu grid: its fields as columns, its records as rows
that the database sorts, filters and searches as the person asks, and
each edit, new row and deletion written through your Cardbox module (its
checks, its `c:Cardbox.allow?/3`, its events).

    <Cardbox.Masu.table cardbox={MyApp.Cardbox} collection={@collection} view={@view}
      actor={@user} people={@people} searchable height="100%" />

`table/1` draws choices as chips in their colors, people by name and
relations by the titles of the records they link to. `grid/3` gives the
plain attributes of `Masu.Components.data_grid/1` instead, for a grid of
your own `:col` slots. Their options:

  * `view` - a saved `Cardbox.View`: its query is the grid's own, which
    the person's sorts and filters narrow, and its options its columns
    (`columns`, `hidden`, `widths`);
  * `actor` - who edits, for the writes (and `"me"` in the view's query);
  * `people` - the people a person field picks from, `%{id, name}` (and a
    `color`); without them, a person is their id;
  * `id` - the grid's id, `"cardbox-<collection id>"` unless given;
  * `time_zone` - where the days of the view's date filters are.

A grid shows other people's changes when its LiveView passes the
collection's events on (`relay/2`):

    def handle_info({:cardbox, event}, socket) do
      Cardbox.Masu.relay(event, "cardbox-#{socket.assigns.collection.id}")
      {:noreply, socket}
    end

## Columns

| Field | Column |
| --- | --- |
| text, url, email, phone | `:text` |
| number | `:integer` (format `integer`) or `:number` |
| checkbox | `:boolean` |
| date | `:date`, or `:datetime` with a time |
| select, status | `:enum` of the choices' names, in their order |
| person | `:enum` of the people's names, or `:text` of ids |
| multi-select, relation, several people | the names or titles, read-only |
| created at, updated at, by | read-only |

A cell takes what a person types as Cardbox takes a value: a choice by
its name, a date as the grid's editor gives it.

`table/1` draws chips as `<span class="cardbox-choice" data-color="blue">`
(Erabi's nine colors), links as `<span class="cardbox-link">` and people
as `<span class="cardbox-person">`, for your style sheet.

# `columns`

```elixir
@spec columns(Cardbox.Collection.t(), Cardbox.View.t() | nil, list()) :: [keyword()]
```

The columns of a collection's fields, in the view's order and with its widths.

# `grid`

```elixir
@spec grid(module(), Cardbox.Collection.t(), keyword()) :: keyword()
```

The attributes of a `<.data_grid>` of a collection.

# `relay`

```elixir
@spec relay(Cardbox.Event.t(), String.t()) :: :ok
```

Passes a collection's event (`Cardbox.Event`) to the grid of that id in
this LiveView, which reads its rows again.

# `row`

```elixir
@spec row(Cardbox.Collection.t(), Cardbox.Record.t(), map(), list()) :: map()
```

A record as a grid's row: the value of each field, by key, as its column
sorts and shows it (a choice's name, a person's name, the titles of
linked records). `titles` are the titles of the records relations link
to, by id.

# `table`

A collection as a Masu grid, with chips for choices, people and relations.
## Attributes

* `cardbox` (`:atom`) (required) - your Cardbox module.
* `collection` (`Cardbox.Collection`) (required)
* `view` (`Cardbox.View`) - Defaults to `nil`.
* `actor` (`:any`) - Defaults to `nil`.
* `people` (`:list`) - Defaults to `[]`.
* `id` (`:string`) - Defaults to `nil`.
* `time_zone` (`:string`) - Defaults to `nil`.
* Global attributes are accepted. attributes of `Masu.Components.data_grid/1`. Supports all globals plus: `["searchable", "height", "max_height", "wheel", "url", "history", "issho", "user", "scope", "locale"]`.

---

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