### Install Ash Backpex dependency Source: https://hexdocs.pm/ash_backpex/index.html Add the library to your mix.exs file. ```elixir def deps do [ {:ash_backpex, "~> 0.1.12"} ] end ``` -------------------------------- ### BasicSearch.apply/3 Examples Source: https://hexdocs.pm/ash_backpex/AshBackpex.BasicSearch.html Usage examples for applying search filters to an Ash query. ```elixir iex> query = MyApp.Post |> Ash.Query.new() iex> AshBackpex.BasicSearch.apply(query, %{"search" => "elixir"}, MyPostLive) #Ash.Query<...> iex> # No search term - query unchanged iex> AshBackpex.BasicSearch.apply(query, %{}, MyPostLive) #Ash.Query<...> ``` -------------------------------- ### Apply filter with module example Source: https://hexdocs.pm/ash_backpex/AshBackpex.Adapter.html Example usage of applying a filter using a specific module implementation. ```elixir iex> query = Ash.Query.new(MyResource) iex> apply_filter_with_module(query, :published, ["true"], AshBackpex.Filters.Boolean, %{}) # Returns query with filter: published == true ``` -------------------------------- ### Resolve function example Source: https://hexdocs.pm/ash_backpex/AshBackpex.LoadSelectResolver.html Example usage of the resolve function in an IEx session. ```elixir iex> fields = [title: %{}, author: %{}, word_count: %{}] iex> AshBackpex.LoadSelectResolver.resolve(MyApp.Post, fields) {[:author, :word_count], [:title]} ``` -------------------------------- ### Define a complete LiveResource Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Dsl.html A full example showing the structure of a LiveResource, including resource settings, field definitions, filters, and item actions. ```elixir defmodule MyAppWeb.Admin.PostLive do use AshBackpex.LiveResource backpex do resource MyApp.Blog.Post layout {MyAppWeb.Layouts, :admin} load [:author, :comments] singular_name "Blog Post" plural_name "Blog Posts" init_order %{by: :inserted_at, direction: :desc} per_page_default 25 per_page_options [10, 25, 50, 100] panels [ content: "Content", metadata: "Metadata" ] fields do field :title do searchable true panel :content end field :content do module Backpex.Fields.Textarea rows 15 panel :content end field :status do panel :metadata end field :published_at do format "%B %d, %Y at %H:%M" panel :metadata end field :author do display_field :name live_resource MyAppWeb.Admin.UserLive panel :metadata end field :view_count do only [:show, :index] end end filters do # Select filter - auto-derived from atom with one_of constraint filter :status # Range filter - auto-derived from datetime attribute filter :published_at # Boolean filter - auto-derived from boolean attribute filter :featured # Range filter - auto-derived from integer attribute filter :view_count # MultiSelect filter - auto-derived from {:array, :atom} with one_of filter :tags end item_actions do strip_default [:delete] action :publish, MyApp.ItemActions.Publish action :archive, MyApp.ItemActions.Archive end end end ``` -------------------------------- ### Common Field Mapping Use Cases Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.html Examples for mapping specific types like Rich Text, Money, or overriding default string behavior. ```elixir config :ash_backpex, field_type_mappings: %{ MyApp.Types.RichText => MyApp.Fields.TiptapEditor } ``` ```elixir config :ash_backpex, field_type_mappings: %{ Money.Ecto.Composite.Type => Backpex.Fields.Currency } ``` ```elixir config :ash_backpex, field_type_mappings: %{ Ash.Type.String => Backpex.Fields.Textarea } ``` -------------------------------- ### Retrieve read action Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Functions to get the read action used for resources, defaulting to the primary read action. ```elixir @spec backpex_read_action(dsl_or_extended :: module() | map()) :: {:ok, atom()} | :error ``` ```elixir @spec backpex_read_action!(dsl_or_extended :: module() | map()) :: atom() | no_return() ``` -------------------------------- ### Get a database record Source: https://hexdocs.pm/ash_backpex/AshBackpex.Adapter.html Retrieves a record by its primary key value. Returns nil if no record is found. ```elixir @spec get(String.t(), keyword(), map(), module()) :: {:ok, [map()]} | {:error, term()} ``` -------------------------------- ### Retrieve update action Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Gets the update action configured for the resource, defaulting to the primary update action. ```elixir @spec backpex_update_action(dsl_or_extended :: module() | map()) :: {:ok, atom()} | :error ``` ```elixir @spec backpex_update_action!(dsl_or_extended :: module() | map()) :: atom() | no_return() ``` -------------------------------- ### Retrieve singular resource name Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Gets the singular display name for the resource used in the admin interface. ```elixir @spec backpex_singular_name(dsl_or_extended :: module() | map()) :: {:ok, String.t()} | :error ``` ```elixir @spec backpex_singular_name!(dsl_or_extended :: module() | map()) :: String.t() | no_return() ``` -------------------------------- ### Retrieve plural name Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Functions to get the plural name of the resource for admin display. ```elixir @spec backpex_plural_name(dsl_or_extended :: module() | map()) :: {:ok, String.t()} | :error ``` ```elixir @spec backpex_plural_name!(dsl_or_extended :: module() | map()) :: String.t() | no_return() ``` -------------------------------- ### Convert Filter to Ash Expression Source: https://hexdocs.pm/ash_backpex/AshBackpex.Filters.MultiSelect.html Examples of converting multi-select filter values into Ash expressions using to_ash_expr/3. ```elixir iex> MultiSelect.to_ash_expr(:status, ["active", "pending"], %{}) #Ash.Expr iex> MultiSelect.to_ash_expr(:status, ["active"], %{}) #Ash.Expr iex> MultiSelect.to_ash_expr(:status, [], %{}) nil iex> MultiSelect.to_ash_expr(:status, nil, %{}) nil ``` -------------------------------- ### Convert range filter to Ash expression Source: https://hexdocs.pm/ash_backpex/AshBackpex.Filters.Range.html Examples of using to_ash_expr/3 to generate Ash expressions from range filter maps. ```elixir iex> Range.to_ash_expr(:price, %{"start" => "10", "end" => "100"}, %{}) #Ash.Expr= 10 and price <= 100> iex> Range.to_ash_expr(:price, %{"start" => "10", "end" => ""}, %{}) #Ash.Expr= 10> iex> Range.to_ash_expr(:price, %{"start" => "", "end" => "100"}, %{}) #Ash.Expr iex> Range.to_ash_expr(:price, %{"start" => "", "end" => ""}, %{}) nil iex> Range.to_ash_expr(:price, nil, %{}) nil ``` -------------------------------- ### Retrieve backpex_init_order! Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Returns the default initialization order, raising on error. ```elixir @spec backpex_init_order!(dsl_or_extended :: module() | map()) :: ((any() -> any()) | {module(), list()}) | no_return() ``` -------------------------------- ### Retrieve backpex_init_order Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Returns the default initialization order when no other options are provided. ```elixir @spec backpex_init_order(dsl_or_extended :: module() | map()) :: {:ok, (any() -> any()) | {module(), list()}} | :error ``` -------------------------------- ### Retrieve backpex_panels configuration Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Returns the panels for admin create/edit forms as a keyword list. ```elixir @spec backpex_panels(dsl_or_extended :: module() | map()) :: {:ok, keyword()} | :error ``` ```elixir @spec backpex_panels!(dsl_or_extended :: module() | map()) :: keyword() | no_return() ``` -------------------------------- ### Retrieve backpex_options configuration Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Returns a map of configured or default DSL options. ```elixir @spec backpex_options(dsl_or_extended :: module() | map()) :: %{ required(atom()) => any() } ``` -------------------------------- ### backpex_create_action!/1 Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Retrieves the create action to be used when creating resources, raising an error if not found. ```APIDOC ## backpex_create_action!(dsl_or_extended) ### Description Retrieves the create action to be used when creating resources. Will default to the primary create action. ### Parameters - **dsl_or_extended** (module() | map()) - Required - The DSL module or extended map. ### Returns - **atom() | no_return()** - Returns the action name or raises an error. ``` -------------------------------- ### Retrieve backpex_on_mount! configuration Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Returns the list of hooks to attach to the mount lifecycle. ```elixir @spec backpex_on_mount!(dsl_or_extended :: module() | map()) :: (:mod_arg | atom() | [:mod_arg | atom()]) | no_return() ``` -------------------------------- ### backpex_create_action/1 Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Retrieves the create action to be used when creating resources. Defaults to the primary create action. ```APIDOC ## backpex_create_action(dsl_or_extended) ### Description Retrieves the create action to be used when creating resources. Will default to the primary create action. ### Parameters - **dsl_or_extended** (module() | map()) - Required - The DSL module or extended map. ### Returns - **{:ok, atom()} | :error** - Returns the action name or an error. ``` -------------------------------- ### Retrieve create action Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Returns the create action for the resource, defaulting to the primary create action. ```elixir @spec backpex_create_action(dsl_or_extended :: module() | map()) :: {:ok, atom()} | :error ``` ```elixir @spec backpex_create_action!(dsl_or_extended :: module() | map()) :: atom() | no_return() ``` -------------------------------- ### Retrieve backpex_layout! Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Returns the configured liveview layout, raising on error. ```elixir @spec backpex_layout!(dsl_or_extended :: module() | map()) :: ((any() -> any()) | {:module, atom()}) | no_return() ``` -------------------------------- ### Retrieve backpex_layout Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Returns the configured liveview layout. ```elixir @spec backpex_layout(dsl_or_extended :: module() | map()) :: {:ok, (any() -> any()) | {:module, atom()}} | :error ``` -------------------------------- ### Retrieve backpex_per_page_options configuration Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Returns the available page size options. ```elixir @spec backpex_per_page_options(dsl_or_extended :: module() | map()) :: {:ok, [integer()]} | :error ``` -------------------------------- ### Configure AshBackpex.LiveResource Source: https://hexdocs.pm/ash_backpex/AshBackpex.Adapter.html Use AshBackpex.LiveResource to automatically configure the adapter for an Ash resource. ```elixir defmodule MyAppWeb.Admin.PostLive do use AshBackpex.LiveResource backpex do resource MyApp.Blog.Post layout {MyAppWeb.Layouts, :admin} fields do field :title field :author end end end ``` -------------------------------- ### Retrieve backpex_item_actions_strip_default! Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Returns the default Backpex actions to remove from the live resource, raising on error. ```elixir @spec backpex_item_actions_strip_default!(dsl_or_extended :: module() | map()) :: [atom()] | no_return() ``` -------------------------------- ### Retrieve backpex_on_mount Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Returns the list of hooks to attach to the mount lifecycle. ```elixir @spec backpex_on_mount(dsl_or_extended :: module() | map()) :: {:ok, :mod_arg | atom() | [:mod_arg | atom()]} | :error ``` -------------------------------- ### Retrieve backpex_item_actions_options Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Returns a map containing configured or default values for backpex.item_actions. ```elixir @spec backpex_item_actions_options(dsl_or_extended :: module() | map()) :: %{ required(atom()) => any() } ``` -------------------------------- ### Define Resource Fields, Relationships, and Calculations Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.html Configure how resources are displayed, including preloading relationships and defining fields for calculations and aggregates. ```elixir backpex do resource MyApp.Blog.Post layout {MyAppWeb.Layouts, :admin} load [:author, :comments] # Preload relationships fields do field :title field :author do # belongs_to relationship display_field :name live_resource MyAppWeb.Admin.UserLive end field :word_count # calculation field :comment_count # aggregate end end ``` -------------------------------- ### Resolve Ash loads and selects Source: https://hexdocs.pm/ash_backpex/AshBackpex.LoadSelectResolver.html Demonstrates how to use the resolver to map Backpex field configurations to Ash query requirements. ```elixir fields = [ title: %{module: Backpex.Fields.Text}, author: %{module: Backpex.Fields.BelongsTo}, word_count: %{module: Backpex.Fields.Number} ] {loads, selects} = AshBackpex.LoadSelectResolver.resolve(MyApp.Blog.Post, fields) # loads => [:author, :word_count] # selects => [:title] ``` -------------------------------- ### Retrieve per-page options Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Returns the list of available page size numbers for the resource. ```elixir @spec backpex_per_page_options!(dsl_or_extended :: module() | map()) :: [integer()] | no_return() ``` -------------------------------- ### Configure admin layout Source: https://hexdocs.pm/ash_backpex/getting-started.html Define an admin layout using Backpex components in your Phoenix layout module. ```elixir # lib/my_app_web/components/layouts.ex defmodule MyAppWeb.Layouts do use MyAppWeb, :html import Backpex.HTML.Layout attr :flash, :map, required: true attr :fluid?, :boolean, default: false attr :current_url, :string, required: true slot :inner_block, required: true def admin(assigns) do ~H""" <.app_shell fluid={@fluid?}> <:topbar> <.topbar_branding /> <.topbar_dropdown> <:label>
  • <.link href={~p"/"} class="flex justify-between hover:bg-base-200">

    Back to App

  • <:sidebar> <.sidebar_item current_url={@current_url} navigate={~p"/admin/posts"}> Posts <%!-- Add more sidebar items for your resources --%> <.flash_messages flash={@flash} /> {render_slot(@inner_block)} """ end end ``` -------------------------------- ### Define a LiveResource Source: https://hexdocs.pm/ash_backpex/index.html Create an admin interface by using AshBackpex.LiveResource in a LiveView module. ```elixir # myapp_web/live/admin/post_live.ex defmodule MyAppWeb.Live.Admin.PostLive do use AshBackpex.LiveResource backpex do resource MyApp.Blog.Post load [:author] layout &MyAppWeb.Layouts.admin/1 fields do field :title field :published_at field :author do display_field(:name) live_resource(MyAppWeb.Live.Admin.AuthorLive) end end end end ``` -------------------------------- ### Retrieve backpex_item_actions Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Returns the list of backpex.item_actions DSL entities. ```elixir @spec backpex_item_actions(dsl_or_extended :: module() | map()) :: [struct()] ``` -------------------------------- ### Set Initial Sorting Source: https://hexdocs.pm/ash_backpex/AshBackpex.Adapter.html Define the default sorting order for the resource list using init_order. ```elixir backpex do resource MyApp.Blog.Post layout {MyAppWeb.Layouts, :admin} init_order %{by: :inserted_at, direction: :desc} end ``` -------------------------------- ### Configure Resource Relationships Source: https://hexdocs.pm/ash_backpex/getting-started.html Define relationships and specify the display field and target LiveView resource for navigation. ```elixir backpex do resource MyApp.Blog.Post layout {MyAppWeb.Layouts, :admin} load [:author] # Preload the relationship fields do field :title field :author do display_field :name live_resource MyAppWeb.Admin.UserLive end end end ``` -------------------------------- ### Retrieve backpex_per_page_default configuration Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Returns the default page size number. ```elixir @spec backpex_per_page_default(dsl_or_extended :: module() | map()) :: {:ok, integer()} | :error ``` ```elixir @spec backpex_per_page_default!(dsl_or_extended :: module() | map()) :: integer() | no_return() ``` -------------------------------- ### Create a Custom Filter Module Source: https://hexdocs.pm/ash_backpex/AshBackpex.Filters.Filter.html Implement the AshBackpex.Filters.Filter behavior to define custom query filtering logic. ```elixir defmodule MyApp.Filters.CustomStatus do use Backpex.Filters.Select @behaviour AshBackpex.Filters.Filter @impl AshBackpex.Filters.Filter def to_ash_expr(field, value, _assigns) do require Ash.Expr Ash.Expr.expr(^Ash.Expr.ref(field) == ^value) end end ``` -------------------------------- ### Retrieve backpex_destroy_action! Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Returns the destroy action for the resource, defaulting to the primary destroy action. ```elixir @spec backpex_destroy_action!(dsl_or_extended :: module() | map()) :: atom() | no_return() ``` -------------------------------- ### backpex_resource!/1 Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Retrieves the Ash resource connected to the Backpex Live resource, raising an error if not found. ```APIDOC ## backpex_resource!(dsl_or_extended) ### Description The Ash resource that the Backpex Live resource should be connected to. ### Signature `backpex_resource!(dsl_or_extended :: module() | map()) :: atom() | no_return()` ``` -------------------------------- ### Retrieve PubSub configuration Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Functions to retrieve the PubSub topic and server configuration. ```elixir @spec backpex_pubsub(dsl_or_extended :: module() | map()) :: {:ok, topic: String.t(), server: atom()} | :error ``` ```elixir @spec backpex_pubsub!(dsl_or_extended :: module() | map()) :: [topic: String.t(), server: atom()] | no_return() ``` -------------------------------- ### Check backpex_fluid? Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Determines if the layout fills the entire width. ```elixir @spec backpex_fluid?(dsl_or_extended :: module() | map()) :: boolean() ``` -------------------------------- ### Add admin routes Source: https://hexdocs.pm/ash_backpex/getting-started.html Register the LiveResource in your Phoenix router. ```elixir # lib/my_app_web/router.ex scope "/admin", MyAppWeb.Admin do pipe_through [:browser] live "/posts", PostLive end ``` -------------------------------- ### Implement Filter Callbacks Source: https://hexdocs.pm/ash_backpex/AshBackpex.Filters.MultiSelect.html Required callbacks for defining the prompt text and available options for the filter. ```elixir @impl Backpex.Filters.MultiSelect def prompt, do: "Select..." @impl Backpex.Filters.MultiSelect def options(_assigns) do [ {"Label 1", "value1"}, {"Label 2", "value2"} ] end ``` -------------------------------- ### Retrieve backpex_item_actions_strip_default Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Returns the default Backpex actions to remove from the live resource. ```elixir @spec backpex_item_actions_strip_default(dsl_or_extended :: module() | map()) :: {:ok, [atom()]} | :error ``` -------------------------------- ### backpex_resource/1 Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Retrieves the Ash resource connected to the Backpex Live resource. ```APIDOC ## backpex_resource(dsl_or_extended) ### Description The Ash resource that the Backpex Live resource should be connected to. ### Signature `backpex_resource(dsl_or_extended :: module() | map()) :: {:ok, atom()} | :error` ``` -------------------------------- ### Implement a custom Select filter Source: https://hexdocs.pm/ash_backpex/AshBackpex.Filters.Select.html Define a custom filter module by using AshBackpex.Filters.Select and implementing the required label, prompt, and options callbacks. ```elixir defmodule MyApp.Filters.Status do use AshBackpex.Filters.Select @impl Backpex.Filter def label, do: "Status" @impl Backpex.Filters.Select def prompt, do: "Select status..." @impl Backpex.Filters.Select def options(_assigns) do [ {"Draft", "draft"}, {"Published", "published"}, {"Archived", "archived"} ] end end ``` -------------------------------- ### Retrieve Backpex resource Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Fetches the Ash resource associated with the Backpex Live resource. ```elixir @spec backpex_resource(dsl_or_extended :: module() | map()) :: {:ok, atom()} | :error ``` ```elixir @spec backpex_resource!(dsl_or_extended :: module() | map()) :: atom() | no_return() ``` -------------------------------- ### Configure item actions in LiveResource Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Dsl.html Use the item_actions block to strip default actions and define custom ones. ```elixir item_actions do # Remove default actions strip_default [:delete] # Add custom actions action :publish, MyApp.ItemActions.Publish action :archive, MyApp.ItemActions.Archive end ``` -------------------------------- ### Enable Searchable Fields Source: https://hexdocs.pm/ash_backpex/getting-started.html Configure fields to be searchable within the Backpex resource definition. ```elixir fields do field :title do searchable true end field :content do searchable true module Backpex.Fields.Textarea end end ``` -------------------------------- ### List items by criteria Source: https://hexdocs.pm/ash_backpex/AshBackpex.Adapter.html Retrieves a list of items matching the specified criteria and fields. ```elixir @spec list(keyword(), keyword(), map(), module()) :: {:ok, [map()]} | {:error, term()} ``` -------------------------------- ### Retrieve backpex_fields Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Returns the list of backpex.fields DSL entities. ```elixir @spec backpex_fields(dsl_or_extended :: module() | map()) :: [struct()] ``` -------------------------------- ### Retrieve create changeset Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Returns the changeset function for creating items, accepting metadata like assigns and target. ```elixir @spec backpex_create_changeset(dsl_or_extended :: module() | map()) :: {:ok, (any(), any(), any() -> any())} | :error ``` ```elixir @spec backpex_create_changeset!(dsl_or_extended :: module() | map()) :: (any(), any(), any() -> any()) | no_return() ``` -------------------------------- ### Configure Searchable Fields in LiveResource Source: https://hexdocs.pm/ash_backpex/AshBackpex.BasicSearch.html Mark fields as searchable within the backpex configuration block to enable automatic search functionality. ```elixir defmodule MyAppWeb.Admin.PostLive do use AshBackpex.LiveResource backpex do resource MyApp.Blog.Post layout {MyAppWeb.Layouts, :admin} fields do field :title do searchable true end field :content do searchable true end field :author_name # Not searchable end end end ``` -------------------------------- ### Organize Forms with Panels Source: https://hexdocs.pm/ash_backpex/getting-started.html Group fields into distinct panels to improve form layout and organization. ```elixir backpex do resource MyApp.Blog.Post layout {MyAppWeb.Layouts, :admin} panels [ content: "Content", settings: "Settings" ] fields do field :title do panel :content end field :content do panel :content module Backpex.Fields.Textarea end field :published do panel :settings end field :status do panel :settings end end end ``` -------------------------------- ### Retrieve backpex_filters Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Returns the list of backpex.filters DSL entities. ```elixir @spec backpex_filters(dsl_or_extended :: module() | map()) :: [struct()] ``` -------------------------------- ### backpex_create_changeset/1 Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Retrieves the changeset function to use when creating items. ```APIDOC ## backpex_create_changeset(dsl_or_extended) ### Description Changeset to use when creating items. Additional metadata is passed as a keyword list via the third parameter. ### Parameters - **dsl_or_extended** (module() | map()) - Required - The DSL module or extended map. ### Returns - **{:ok, (any(), any(), any() -> any())} | :error** - Returns the changeset function or an error. ``` -------------------------------- ### Create a LiveResource Source: https://hexdocs.pm/ash_backpex/getting-started.html Define a LiveResource module to manage your Ash resource within the admin interface. ```elixir # lib/my_app_web/live/admin/post_live.ex defmodule MyAppWeb.Admin.PostLive do use AshBackpex.LiveResource backpex do resource MyApp.Blog.Post layout {MyAppWeb.Layouts, :admin} fields do field :title field :content do module Backpex.Fields.Textarea end field :published field :inserted_at end end end ``` -------------------------------- ### Retrieve destroy action Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Returns the destroy action for the resource, defaulting to the primary destroy action. ```elixir @spec backpex_destroy_action(dsl_or_extended :: module() | map()) :: {:ok, atom()} | :error ``` -------------------------------- ### Configure Automatic Loads Source: https://hexdocs.pm/ash_backpex/AshBackpex.Adapter.html Specify additional relationships, calculations, or aggregates to load automatically. ```elixir backpex do resource MyApp.Blog.Post layout {MyAppWeb.Layouts, :admin} load [:author, :comments, nested: [:author]] end ``` -------------------------------- ### backpex_singular_name!/1 Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Retrieves the singular name for the resource used in the admin interface, raising an error if not found. ```APIDOC ## backpex_singular_name!(dsl_or_extended) ### Description The singular name for the resource that will appear in the admin. E.g., "Post" ### Signature `backpex_singular_name!(dsl_or_extended :: module() | map()) :: String.t() | no_return()` ``` -------------------------------- ### Retrieve backpex_full_text_search! Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Returns the name of the generated column used for full text search, raising on error. ```elixir @spec backpex_full_text_search!(dsl_or_extended :: module() | map()) :: atom() | no_return() ``` -------------------------------- ### AshBackpex.BasicSearch.apply/3 Source: https://hexdocs.pm/ash_backpex/AshBackpex.BasicSearch.html Applies search filters to an Ash query based on searchable fields defined in the provided LiveResource module. ```APIDOC ## apply(query, params, live_resource) ### Description Applies search filters to an Ash query based on searchable fields. If the params map contains a "search" key, it builds an Ash filter using 'contains' expressions joined by OR logic for all fields marked as searchable in the LiveResource. ### Signature `apply(query(), params(), live_resource()) :: query()` ### Parameters - **query** (Ash.Query.t()) - The Ash query to be filtered. - **params** (map()) - A map containing the search term under the "search" key. - **live_resource** (module()) - The module that uses AshBackpex.LiveResource. ### Example ```elixir query = MyApp.Post |> Ash.Query.new() params = %{"search" => "elixir"} filtered_query = AshBackpex.BasicSearch.apply(query, params, MyPostLive) ``` ``` -------------------------------- ### Customize Resource Display Names Source: https://hexdocs.pm/ash_backpex/getting-started.html Override the default singular and plural labels for the resource. ```elixir backpex do resource MyApp.Blog.Post layout {MyAppWeb.Layouts, :admin} singular_name "Blog Post" plural_name "Blog Posts" fields do # ... end end ``` -------------------------------- ### Implement Custom Changeset Functions Source: https://hexdocs.pm/ash_backpex/AshBackpex.Adapter.html Provide custom changeset functions for advanced control over create and update operations. ```elixir backpex do resource MyApp.Blog.Post layout {MyAppWeb.Layouts, :admin} create_changeset fn item, params, metadata -> assigns = Keyword.get(metadata, :assigns) target = Keyword.get(metadata, :target) Ash.Changeset.for_create(item.__struct__, :create, params, actor: assigns.current_user ) end end ``` -------------------------------- ### backpex_update_action!/1 Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Retrieves the update action configured for the resource, raising an error if not found. ```APIDOC ## backpex_update_action!(dsl_or_extended) ### Description The update action to be used when updating resources. Will default to the primary update action. ### Signature `backpex_update_action!(dsl_or_extended :: module() | map()) :: atom() | no_return()` ``` -------------------------------- ### Configure Custom Item Actions Source: https://hexdocs.pm/ash_backpex/getting-started.html Modify available item actions by stripping defaults or adding custom action modules. ```elixir backpex do resource MyApp.Blog.Post layout {MyAppWeb.Layouts, :admin} item_actions do strip_default [:delete] # Remove delete action action :archive, MyApp.ItemActions.Archive end fields do # ... end end ``` -------------------------------- ### Configure Custom CRUD Actions Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.html Specify custom Ash actions for CRUD operations within the backpex block. ```elixir backpex do resource MyApp.Blog.Post layout {MyAppWeb.Layouts, :admin} create_action :admin_create read_action :admin_read update_action :admin_update destroy_action :soft_delete end ``` -------------------------------- ### backpex_update_action/1 Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Retrieves the update action configured for the resource. ```APIDOC ## backpex_update_action(dsl_or_extended) ### Description The update action to be used when updating resources. Will default to the primary update action. ### Signature `backpex_update_action(dsl_or_extended :: module() | map()) :: {:ok, atom()} | :error` ``` -------------------------------- ### Add Index Filters Source: https://hexdocs.pm/ash_backpex/getting-started.html Implement filters in the index view using specific filter modules. ```elixir backpex do resource MyApp.Blog.Post layout {MyAppWeb.Layouts, :admin} fields do field :title field :published field :status end filters do filter :published do module Backpex.Filters.Boolean end filter :status do module Backpex.Filters.Select end end end ``` -------------------------------- ### Retrieve backpex_full_text_search Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Returns the name of the generated column used for full text search. ```elixir @spec backpex_full_text_search(dsl_or_extended :: module() | map()) :: {:ok, atom()} | :error ``` -------------------------------- ### backpex_update_changeset/1 Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Returns a changeset function for updating items, returning {:ok, function} on success or :error. ```APIDOC ## backpex_update_changeset(dsl_or_extended) ### Description Returns a changeset function used when updating items. Additional metadata is passed as a keyword list via the third parameter. ### Signature `backpex_update_changeset(dsl_or_extended :: module() | map()) :: {:ok, (any(), any(), any() -> any())} | :error` ### Parameters - **dsl_or_extended** (module | map) - The DSL module or extended map configuration. ### Metadata - **:assigns** - The assigns. - **:target** - The name of the form target that triggered the changeset call (defaults to nil). ``` -------------------------------- ### field_type_mappings(otp_app \ nil) Source: https://hexdocs.pm/ash_backpex/AshBackpex.Config.html Reads the field type mappings configuration, checking app-scoped config first, then falling back to global config. ```APIDOC ## field_type_mappings(otp_app \\ nil) ### Description Reads the field type mappings configuration. Checks app-scoped config first, then falls back to global config. Returns nil if no configuration is found. ### Parameters - **otp_app** (atom | nil) - Optional - The OTP application name to check for app-scoped config. ### Returns - (map | function | nil) - The configured field type mappings or nil. ``` -------------------------------- ### Define BasicSearch Types Source: https://hexdocs.pm/ash_backpex/AshBackpex.BasicSearch.html Type definitions for the BasicSearch module. ```elixir @type live_resource() :: module() ``` ```elixir @type params() :: map() ``` ```elixir @type query() :: Ash.Query.t() ``` -------------------------------- ### backpex_singular_name/1 Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Retrieves the singular name for the resource used in the admin interface. ```APIDOC ## backpex_singular_name(dsl_or_extended) ### Description The singular name for the resource that will appear in the admin. E.g., "Post" ### Signature `backpex_singular_name(dsl_or_extended :: module() | map()) :: {:ok, String.t()} | :error` ``` -------------------------------- ### Introspect LiveResource configuration Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Use these functions to retrieve configuration details like the underlying Ash resource or defined fields for a given LiveResource module. ```elixir # Get the Ash resource for a LiveResource AshBackpex.LiveResource.Info.backpex_resource(MyAppWeb.Admin.PostLive) # => MyApp.Blog.Post # Get configured fields AshBackpex.LiveResource.Info.backpex_fields(MyAppWeb.Admin.PostLive) # => [%AshBackpex.LiveResource.Dsl.Field{attribute: :title, ...}, ...] ``` -------------------------------- ### backpex_destroy_action/1 Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.Info.html Retrieves the destroy action to be used when destroying resources. ```APIDOC ## backpex_destroy_action(dsl_or_extended) ### Description The destroy action to be used when destroying resources. Will default to the primary destroy action. ### Parameters - **dsl_or_extended** (module() | map()) - Required - The DSL module or extended map. ### Returns - **{:ok, atom()} | :error** - Returns the action name or an error. ``` -------------------------------- ### Configure Parent Actions for InlineCRUD Source: https://hexdocs.pm/ash_backpex/inline-crud.html Define create and update actions in the parent resource using manage_relationship with type :direct_control to handle nested resource operations. ```elixir defmodule Demo.Blog.Post do use Ash.Resource, domain: Demo.Blog, data_layer: AshSqlite.DataLayer actions do create :admin_create do # Post attributes and other relationship arguments are omitted here. argument :comments, {:array, :map}, allow_nil?: true change manage_relationship(:comments, type: :direct_control) end update :admin_update do # Post attributes and other relationship arguments are omitted here. require_atomic? false argument :comments, {:array, :map}, allow_nil?: true change manage_relationship(:comments, type: :direct_control) end end end ``` -------------------------------- ### Configure field type mappings Source: https://hexdocs.pm/ash_backpex/AshBackpex.Config.html Define field type mappings in config/config.exs, supporting both global and app-specific overrides. ```elixir config :my_app, AshBackpex, field_type_mappings: %{...} ``` ```elixir config :ash_backpex, field_type_mappings: %{...} ``` ```elixir # Global config (applies to all apps using AshBackpex) config :ash_backpex, field_type_mappings: %{ MyApp.Types.Money => Backpex.Fields.Currency } # App-specific config (overrides global for this app) config :my_app, AshBackpex, field_type_mappings: %{ MyApp.Types.Money => MyApp.Fields.MoneyField } ``` -------------------------------- ### Configure typeahead relationship fields Source: https://hexdocs.pm/ash_backpex/index.html Enable server-backed search for large belongs_to relationships. ```elixir field :author do display_field :name typeahead true typeahead_limit 10 debounce 300 prompt "Choose an author" end ``` -------------------------------- ### Define a custom Boolean filter Source: https://hexdocs.pm/ash_backpex/AshBackpex.Filters.Boolean.html Implement a custom filter module by using AshBackpex.Filters.Boolean and defining the label. ```elixir defmodule MyApp.Filters.Published do use AshBackpex.Filters.Boolean @impl Backpex.Filter def label, do: "Published" end ``` -------------------------------- ### Configure LiveResource with InlineCRUD Source: https://hexdocs.pm/ash_backpex/inline-crud.html Integrate InlineCRUD into the LiveResource by specifying the module and defining child fields for the related resource. ```elixir defmodule DemoWeb.PostLive do use AshBackpex.LiveResource backpex do resource Demo.Blog.Post create_action :admin_create update_action :admin_update load [:author, :comments, :topic_tags, :audience_tags, :word_count, :comment_count] panels( content: "Content", publishing: "Publishing", relationships: "Relationships" ) fields do field :comments do module Backpex.Fields.InlineCRUD except [:index] live_resource DemoWeb.CommentLive panel :relationships child_fields do field :body, Backpex.Fields.Textarea do label "Body" rows 3 class "inline-crud-comment-body" end field :author do label "Author" display_field :name typeahead true typeahead_limit 10 prompt "Choose an author" class "w-56" end field :sentiment do label "Sentiment" options Positive: :positive, Neutral: :neutral, Critical: :critical class "w-40" end field :approved do label "Approved" class "w-28" end end end end end end ``` -------------------------------- ### Define field_list type Source: https://hexdocs.pm/ash_backpex/AshBackpex.LoadSelectResolver.html Type definition for the field list configuration. ```elixir @type field_list() :: keyword() ``` -------------------------------- ### Implement the type callback Source: https://hexdocs.pm/ash_backpex/AshBackpex.Filters.Range.html Specify the input type for the range filter by implementing the type/0 callback. ```elixir @impl Backpex.Filters.Range def type, do: :number ``` -------------------------------- ### Define a LiveResource for an Ash resource Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.html Use the AshBackpex.LiveResource DSL to define an admin interface for an Ash resource, specifying layout and field configurations. ```elixir defmodule MyAppWeb.Admin.PostLive do use AshBackpex.LiveResource backpex do resource MyApp.Blog.Post layout {MyAppWeb.Layouts, :admin} fields do field :title field :content do module Backpex.Fields.Textarea end field :published field :author do display_field :name live_resource MyAppWeb.Admin.UserLive end end end end ``` -------------------------------- ### Define Child Resource Actions Source: https://hexdocs.pm/ash_backpex/inline-crud.html Ensure the child resource includes the necessary create and update actions to accept the fields submitted by the repeated form. ```elixir defmodule Demo.Blog.Comment do use Ash.Resource, domain: Demo.Blog, data_layer: AshSqlite.DataLayer attributes do uuid_primary_key :id attribute :body, :string do allow_nil? false public? true end attribute :sentiment, :atom do allow_nil? false default :neutral public? true constraints one_of: [:positive, :neutral, :critical] end attribute :approved, :boolean do allow_nil? false default false public? true end end relationships do belongs_to :post, Demo.Blog.Post do allow_nil? false end belongs_to :author, Demo.Blog.Author do allow_nil? false end end actions do defaults [:read, :destroy] create :create do primary? true accept [:body, :sentiment, :approved, :post_id, :author_id] end update :update do primary? true accept [:body, :sentiment, :approved, :post_id, :author_id] end end end ``` -------------------------------- ### Count items matching criteria Source: https://hexdocs.pm/ash_backpex/AshBackpex.Adapter.html Returns the count of items based on the provided criteria, fields, assigns, and live resource. ```elixir @spec count(keyword(), keyword(), map(), module()) :: {:ok, [map()]} | {:error, term()} ``` -------------------------------- ### Define select type Source: https://hexdocs.pm/ash_backpex/AshBackpex.LoadSelectResolver.html Type definition for select atoms. ```elixir @type select() :: atom() ``` -------------------------------- ### Define a MultiSelect Filter Source: https://hexdocs.pm/ash_backpex/AshBackpex.Filters.MultiSelect.html Implement the MultiSelect filter by defining the label, prompt, and available options. ```elixir defmodule MyApp.Filters.Tags do use AshBackpex.Filters.MultiSelect @impl Backpex.Filter def label, do: "Tags" @impl Backpex.Filters.MultiSelect def prompt, do: "Select tags..." @impl Backpex.Filters.MultiSelect def options(_assigns) do [ {"Bug", "bug"}, {"Feature", "feature"}, {"Enhancement", "enhancement"} ] end end ``` -------------------------------- ### Apply Search Filters Manually Source: https://hexdocs.pm/ash_backpex/AshBackpex.BasicSearch.html Invoke BasicSearch.apply/3 directly to filter an Ash query using search parameters. ```elixir query = MyApp.Blog.Post |> Ash.Query.new() params = %{"search" => "hello"} filtered_query = AshBackpex.BasicSearch.apply(query, params, MyAppWeb.Admin.PostLive) ``` -------------------------------- ### Define Parent Resource Relationship Source: https://hexdocs.pm/ash_backpex/inline-crud.html Configure the parent resource to expose a has_many relationship to the child resource. ```elixir defmodule Demo.Blog.Post do use Ash.Resource, domain: Demo.Blog, data_layer: AshSqlite.DataLayer relationships do has_many :comments, Demo.Blog.Comment end end ``` -------------------------------- ### Set Custom Sort Order Source: https://hexdocs.pm/ash_backpex/getting-started.html Define the default sorting behavior for the resource index view. ```elixir backpex do resource MyApp.Blog.Post layout {MyAppWeb.Layouts, :admin} init_order %{by: :inserted_at, direction: :desc} fields do # ... end end ``` -------------------------------- ### Customize filter options Source: https://hexdocs.pm/ash_backpex/AshBackpex.Filters.Boolean.html Override the options/1 callback to define custom labels and keys for the boolean checkboxes. ```elixir @impl Backpex.Filters.Boolean def options(_assigns) do [ %{label: "Published", key: "true", predicate: nil}, %{label: "Draft", key: "false", predicate: nil} ] end ``` -------------------------------- ### Configure custom field type mappings Source: https://hexdocs.pm/ash_backpex/index.html Map Ash types to Backpex field modules globally or via a function. ```elixir # config/config.exs # Global config (applies to all apps using AshBackpex) config :ash_backpex, field_type_mappings: %{ MyApp.Types.Money => Backpex.Fields.Currency, MyApp.Types.RichText => Backpex.Fields.Textarea } # Or use a function for conditional logic config :ash_backpex, field_type_mappings: fn type, constraints -> case type do MyApp.Types.Money -> Backpex.Fields.Currency _ -> nil # Fall back to default end end ``` -------------------------------- ### Define Field Mappings via Function Source: https://hexdocs.pm/ash_backpex/AshBackpex.LiveResource.html Use a function to implement conditional logic based on type and constraints, returning nil to fall back to default mappings. ```elixir config :ash_backpex, field_type_mappings: fn type, constraints -> case {type, constraints} do # Map Money type to currency field {MyApp.Types.Money, _} -> Backpex.Fields.Currency # Map strings with max_length > 255 to Textarea {Ash.Type.String, constraints} when is_list(constraints) -> if Keyword.get(constraints, :max_length, 0) > 255 do Backpex.Fields.Textarea else nil # Fall back to default end # Return nil to use default mapping _ -> nil end end ``` -------------------------------- ### Configure custom field type mappings Source: https://hexdocs.pm/ash_backpex/readme.html Define global or conditional mappings between Ash types and Backpex field modules in your configuration. ```elixir # config/config.exs # Global config (applies to all apps using AshBackpex) config :ash_backpex, field_type_mappings: %{ MyApp.Types.Money => Backpex.Fields.Currency, MyApp.Types.RichText => Backpex.Fields.Textarea } # Or use a function for conditional logic config :ash_backpex, field_type_mappings: fn type, constraints -> case type do MyApp.Types.Money => Backpex.Fields.Currency _ -> nil # Fall back to default end end ``` -------------------------------- ### apply_filter_with_module/5 Source: https://hexdocs.pm/ash_backpex/AshBackpex.Adapter.html Applies a filter to an Ash query using a filter module's to_ash_expr/3 callback. ```APIDOC ## apply_filter_with_module(query, field, value, module, assigns) ### Description Applies a filter to the query using a filter module's `to_ash_expr/3` callback. This helper function is used when filters have an associated module that implements the `AshBackpex.Filters.Filter` behavior. ### Parameters - **query** (Ash.Query.t()) - Required - The Ash.Query to apply the filter to - **field** (atom()) - Required - The atom name of the attribute being filtered - **value** (any()) - Required - The filter value from the UI - **module** (module()) - Required - The filter module implementing AshBackpex.Filters.Filter - **assigns** (map()) - Required - The LiveView assigns map ### Returns - **query** (Ash.Query.t()) - The query with the filter applied, or the unchanged query if the filter module returns nil. ### Example ```elixir iex> query = Ash.Query.new(MyResource) iex> apply_filter_with_module(query, :published, ["true"], AshBackpex.Filters.Boolean, %{}) # Returns query with filter: published == true ``` ```