Table actions DSL
v0.0.1
The row_actions, row and bulk_actions sections of a resource's table block declare the buttons on each row, the behavior of a row and the actions on a selection of rows.
row_actions.actions_layout
Names which actions draw inline and which collapse into a dropdown. It sits at mishka_gervaz.table.row_actions.actions_layout.
| Option | Type | Default | Description |
|---|---|---|---|
position | :start | :end | :end | Which side of the row holds the actions. The value is compiled into the config, but no built-in template or handler reads it. |
sticky | boolean | true | Stick on horizontal scroll. |
inline | list(atom) | none | Names of the actions drawn as buttons. Gervaz does not check the names, and a name that matches no action draws nothing. Once this list or dropdown is set, an action that neither names is not drawn. |
dropdown | list(atom) | [] | Names of the dropdown blocks to draw. A dropdown draws only when this list names it. |
auto_collapse_after | integer | none | Meant to fold every action past the Nth into the dropdown. The value is compiled into the config, but no built-in template or handler reads it. |
row_actions.action
Declares one per-row action. The inline form works too: action :expand, type: :accordion. It sits at mishka_gervaz.table.row_actions.action.
Call: action name
Arguments:
| Argument | Type | Default | Description |
|---|---|---|---|
name | atom | none | Required. Action identifier. |
Options:
| Option | Type | Default | Description |
|---|---|---|---|
type | :link | :modal | :event | :edit | :destroy | :update | :accordion | :unarchive | :permanent_destroy | :row_click | module | none | Required. The action type. Built-in types: :link, :modal, :event, :edit, :destroy, :update, :accordion, :unarchive, :permanent_destroy and :row_click. A module that implements the ActionType behaviour also works. The built-in registry has no :modal entry. See Built-in types. |
path | String.t | (any -> any) | none | The link path for :link. A string is used as written, or give a function of the record. An action named :show or :edit goes to the table's route instead of a string path. |
event | atom | String.t | none | Event name to send. |
action | atom | {atom, atom} | none | The Ash action an :update action runs: an atom, or a tuple {master_action, tenant_action}. |
payload | (any -> any) | none | Event payload function fn record -> payload. |
confirm | String.t | (any -> any) | none | A confirmation message shown before the action runs: a string, or a function of the record. Gervaz shows the text as written. The :link and :accordion types ignore it. |
restricted | boolean | false | When true, only master users see the action. |
visible | boolean | :active | :archived | (any, any -> any) | :active | When the action shows. :active (the default) shows it for active records, :archived for archived records, true always and false never. A function fn record, state -> boolean decides for itself. |
js | (any -> any) | none | JS commands chained onto the click: fn record -> JS.exec(...) end. Only the :edit type reads it. |
render | (any -> any) | (any, any -> any) | (any, any, any -> any) | none | Custom HEEx for the control: fn record -> ... end, fn record, action -> ... end or fn record, action, target -> ... end. |
action ui
How the action button is drawn. It sits at mishka_gervaz.table.row_actions.action.ui.
| Option | Type | Default | Description |
|---|---|---|---|
label | String.t | (-> any) | none | Button label. String or fn -> "Label" end for gettext. Defaults to humanized action name. |
icon | String.t | none | Icon identifier. |
class | String.t | none | CSS classes. |
extra | map | %{} | Template-specific options. The value is compiled into the config, but no built-in template or handler reads it. |
row_actions.dropdown
A dropdown menu of actions. It requires a ui block with a label. It sits at mishka_gervaz.table.row_actions.dropdown.
Call: dropdown name
Arguments:
| Argument | Type | Default | Description |
|---|---|---|---|
name | atom | none | Required. Dropdown identifier. |
dropdown action
An action nested in a dropdown. It takes the same options as a top-level action. It sits at mishka_gervaz.table.row_actions.dropdown.action.
Call: action name
Arguments:
| Argument | Type | Default | Description |
|---|---|---|---|
name | atom | none | Required. Action identifier. |
Options:
| Option | Type | Default | Description |
|---|---|---|---|
type | :link | :modal | :event | :edit | :destroy | :update | :accordion | :unarchive | :permanent_destroy | :row_click | module | none | Required. The action type. Built-in types: :link, :modal, :event, :edit, :destroy, :update, :accordion, :unarchive, :permanent_destroy and :row_click. A module that implements the ActionType behaviour also works. The built-in registry has no :modal entry. See Built-in types. |
path | String.t | (any -> any) | none | The link path for :link. A string is used as written, or give a function of the record. An action named :show or :edit goes to the table's route instead of a string path. |
event | atom | String.t | none | Event name to send. |
action | atom | {atom, atom} | none | The Ash action an :update action runs: an atom, or a tuple {master_action, tenant_action}. |
payload | (any -> any) | none | Event payload function fn record -> payload. |
confirm | String.t | (any -> any) | none | A confirmation message shown before the action runs: a string, or a function of the record. Gervaz shows the text as written. The :link and :accordion types ignore it. |
restricted | boolean | false | When true, only master users see the action. |
visible | boolean | :active | :archived | (any, any -> any) | :active | When the action shows. :active (the default) shows it for active records, :archived for archived records, true always and false never. A function fn record, state -> boolean decides for itself. |
js | (any -> any) | none | JS commands chained onto the click: fn record -> JS.exec(...) end. Only the :edit type reads it. |
render | (any -> any) | (any, any -> any) | (any, any, any -> any) | none | Custom HEEx for the control: fn record -> ... end, fn record, action -> ... end or fn record, action, target -> ... end. |
separator
A divider in the dropdown. It sits at mishka_gervaz.table.row_actions.dropdown.separator.
| Option | Type | Default | Description |
|---|---|---|---|
label | String.t | none | Optional separator label. |
dropdown ui
How the dropdown trigger is drawn. It sits at mishka_gervaz.table.row_actions.dropdown.ui.
| Option | Type | Default | Description |
|---|---|---|---|
label | String.t | (-> any) | none | Required. Button label. String or fn -> "Label" end for gettext. The built-in dropdown button draws only its icon. |
icon | String.t | none | Icon identifier. |
class | String.t | none | CSS classes. The built-in dropdown button draws only its icon. |
extra | map | %{} | Template-specific options. The built-in dropdown button draws only its icon. |
row
Selection, row click, per-row classes and whole-row replacement. It sits at mishka_gervaz.table.row.
| Option | Type | Default | Description |
|---|---|---|---|
event | String.t | none | The event a click on the row sends. The value is compiled into the config, but no built-in template or handler reads it. |
payload | (any -> any) | map | none | Payload for row click. Map or fn record -> map. The value is compiled into the config, but no built-in template or handler reads it. |
selectable | boolean | false | Declares that rows can be selected. This makes source.actions.get required. The checkboxes appear when the template has the :select feature and at least one bulk action is visible, whatever this option says. |
class
Per-row classes. It sits at mishka_gervaz.table.row.class.
| Option | Type | Default | Description |
|---|---|---|---|
possible | list(String.t) | [] | Every class that apply can return. Tailwind scans source files, so listing the literals here keeps them in the build. Nothing reads the list at runtime. |
apply | (any -> any) | none | Returns the class for one row: fn record -> class | nil. |
override
Replaces how a row is drawn. It sits at mishka_gervaz.table.row.override.
| Option | Type | Default | Description |
|---|---|---|---|
component | atom | none | A LiveComponent that draws the whole row. |
render | (any, any, any -> any) | none | A function that draws the whole row: fn assigns, record, columns -> HEEx. |
condition | (any -> any) | none | The override applies only when fn record -> boolean returns true. |
bulk_actions
Actions on a selection of rows. At least one action is required in the block. It sits at mishka_gervaz.table.bulk_actions.
| Option | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Enable bulk actions. Setting it to false has no effect in the built-in action builder. |
action
Declares one bulk action. The inline form works too: action :archive, type: :destroy, confirm: "Archive selected?". It sits at mishka_gervaz.table.bulk_actions.action.
Call: action name
Arguments:
| Argument | Type | Default | Description |
|---|---|---|---|
name | atom | none | Required. Action identifier. |
Options:
| Option | Type | Default | Description |
|---|---|---|---|
type | :event | :destroy | :update | :unarchive | :permanent_destroy | none | A built-in type resolves the handler for you. :event sends an event to the parent LiveView. :destroy soft-deletes with source.actions.destroy. :update runs the Ash action in action. :unarchive restores with the archive restore action. :permanent_destroy deletes archived records with the archive destroy action. When both type and handler are set, handler wins. |
action | atom | {atom, atom} | none | The Ash action an :update bulk action runs: an atom, or a tuple {master_action, tenant_action}. |
confirm | boolean | String.t | none | The text of the confirmation dialog. true has no default message. {count} becomes the number of rows the action runs on: the checked rows, or with select all the table's total minus the unchecked rows. With select all, {count} stays as written for a :load_more or :infinite table with show_total false while rows are left to load. |
event | atom | none | Event name for :event type. Defaults to action name if not specified. |
payload | (any -> any) | none | The payload sent with an event: fn selected_ids -> payload. The value is compiled into the config, but no built-in template or handler reads it. |
restricted | boolean | false | Shows the action only to master users. |
visible | :active | :archived | (any -> any) | :active | When the action shows: :active (the default) or :archived, or a function fn state -> boolean. |
handler | atom | (any, any -> any) | {atom, atom} | :parent | Who runs the action. :parent (the default) sends {:bulk_action, name, selected_ids} to the parent LiveView. A function fn selected_ids, state -> {:ok, state} runs in the component. An atom names an Ash action, and a tuple {master_action, tenant_action} names one for each role. A built-in type atom acts as type. With type set, the handler is resolved from it. |
action ui
How the bulk action button is drawn. It sits at mishka_gervaz.table.bulk_actions.action.ui.
| Option | Type | Default | Description |
|---|---|---|---|
label | String.t | (-> any) | none | Button label. String or fn -> "Label" end for gettext. |
icon | String.t | none | Icon identifier. |
class | String.t | none | CSS classes. |
extra | map | %{} | Template-specific options. The value is compiled into the config, but no built-in template or handler reads it. |