Table filters DSL
v0.0.1
The filters and filter_groups sections of a resource's table block declare the filter inputs above the table and the collapsible panels that hold them.
filter
Declares one filter input. The inline form works too: filter :search, :text, fields: [:title, :slug]. It sits at mishka_gervaz.table.filters.filter.
Call: filter name, type
Arguments:
| Argument | Type | Default | Description |
|---|---|---|---|
name | atom | none | Required. Filter identifier. |
type | :text | :select | :boolean | :number | :date | :date_range | :relation | module | :text | Built-in types: :text (the default), :select, :boolean, :number, :date, :date_range and :relation. A module that implements the FilterType behaviour also works. |
Options:
| Option | Type | Default | Description |
|---|---|---|---|
source | atom | none | Source field if different from name. |
fields | list(atom) | none | Search fields for :text type. |
depends_on | atom | none | Parent filter for cascading. |
visible | boolean | (any -> any) | true | Visibility. |
restricted | boolean | (any -> any) | false | When true, only master users see the filter. A function is ignored. |
options | list(any) | (-> any) | none | The choices, as a list or a zero-arity function that returns one. An entry is {label, value}, [label: label, value: value], or a bare value that is its own label. A function runs once, when the table mounts. |
default | any | none | Default value for the filter. Will be pre-selected on initial load. |
presets | list(any) | none | Range presets as [{label, map}]. The value is compiled into the config, but no built-in template or handler reads it. |
display_field | atom | (any -> any) | (any, any -> any) | none | How a relation option is labeled: a field name, a one-argument function that gets the record, or a two-argument function that gets the record and the state. A function of one argument needs search_field as well. With a function of two arguments, the search falls back to the field :name. |
search_field | atom | none | Field to search in (combobox/async). |
include_nil | boolean | String.t | false | Include nil option. |
min | integer | none | Min value for number type. |
max | integer | none | Max value for number type. |
min_chars | integer | 2 | Min chars before search. |
virtual | boolean | false | Marks a filter with no database column of its own. The flag records intent only. What makes such a filter work is resource for the options and apply for the query. |
resource | module | none | Resource to load options from (for virtual). |
load_action | atom | :read | The Ash action that loads the options. For a master user, :read and an unset value pick :master_read when the resource has it, then :read_any, and then :read. |
load | (any, any -> any) | none | Scopes the list of options a relation filter offers: fn query, state -> query. |
apply | (any, any, any -> any) | none | Decides how the chosen value narrows the table query: fn query, value, context -> query. The context is a map with path_params, current_user, master_user?, filter_values and archive_status. |
mode | :static | :load_more | :search | :search_multi | :static | How a relation filter loads its options. :static loads all of them at once. :search searches as the reader types, one choice at a time. :search_multi does the same for several choices. The schema also accepts :load_more, but the built-in relation filter has no input for it and raises when it draws the filter. |
page_size | pos_integer | 20 | Number of options per page when using paginated modes. |
filter ui
How the filter input is drawn. It sits at mishka_gervaz.table.filters.filter.ui.
| Option | Type | Default | Description |
|---|---|---|---|
label | String.t | (-> any) | none | Filter label. String or fn -> gettext(...) end for i18n. |
placeholder | String.t | (-> any) | none | Placeholder text. String or fn -> gettext(...) end for i18n. |
prompt | String.t | "Select..." | The empty choice of a select. Defaults to "Select...". |
disabled_prompt | (-> any) | String.t | none | Prompt when disabled. Can be a string or a zero-arity function. If not set, will show 'Select {parent label} first'. |
icon | String.t | none | Icon identifier. |
debounce | integer | 300 | Debounce in milliseconds. |
extra | map | %{} | Template-specific options. |
filter preload
Relationships a relation filter loads so that display_field can read them. It sits at mishka_gervaz.table.filters.filter.preload.
| Option | Type | Default | Description |
|---|---|---|---|
always | list(any) | none | Relationships to always load, regardless of user type. Example: always [:site, :category] |
tenant | list(any) | none | Relationships to load for tenant users. Example: tenant [:category] |
master | list(any) | none | Relationships to load for master users. Renamed entries work: master [master_category: :category]. |
filter_groups.group
Puts filters that already exist into a collapsible panel. A filter may sit in at most one group. It sits at mishka_gervaz.table.filter_groups.group.
Call: group name
Arguments:
| Argument | Type | Default | Description |
|---|---|---|---|
name | atom | none | Required. Group identifier. |
Options:
| Option | Type | Default | Description |
|---|---|---|---|
filters | list(atom) | none | Required. Filter names belonging to this group. |
collapsed | boolean | true | Start collapsed. |
collapsible | boolean | false | Lets the reader collapse the group. A group that is not collapsible draws inline, with no panel. |
visible | boolean | (any -> any) | true | Static or dynamic visibility. |
restricted | boolean | (any -> any) | false | When true, only master users see the group. A function is ignored. |
position | any | none | Group position (integer, :first, :last). |
group ui
How the group is drawn. It sits at mishka_gervaz.table.filter_groups.group.ui.
| Option | Type | Default | Description |
|---|---|---|---|
label | String.t | (-> any) | none | Group label. |
icon | String.t | none | Group icon. |
description | String.t | none | Group description. The value is compiled into the config, but no built-in template or handler reads it. |
class | String.t | none | Group CSS classes. The value is compiled into the config, but no built-in template or handler reads it. |
header_class | String.t | none | Group header CSS classes. The value is compiled into the config, but no built-in template or handler reads it. |
columns | 1 | 2 | 3 | 4 | 5 | 6 | none | Number of grid columns for this group's filters. The default is 3. Only a collapsible group draws a grid. |
extra | map | %{} | Additional options. The value is compiled into the config, but no built-in template or handler reads it. |