Backpex Documentation

repository·develop·Indexed 21 days ago

https://github.com/naymspace/backpex

A customizable administration panel for Phoenix LiveView applications (version 0.18.0) that enables rapid creation of CRUD interfaces via LiveResources. It features built-in support for search, filters, authorization, various field types, and associations (HasOne, BelongsTo, HasMany(Through)). The library provides mechanisms for implementing Item Actions for specific records and Resource Actions for global operations, including support for custom forms and confirmation dialogs.

Tokens
77.8K
Snippets
249
Records
354
Agent score
68%

What's inside backpex

  1. Overview of Backpex

    develop

    Backpex is a highly customizable administration panel designed specifically for Phoenix LiveView applications. It allows developers to quickly generate CRUD (Create, Read, Update, Delete) views for existing database tables using LiveResource modules.

    Key capabilities include:

    • LiveResources: Configurable modules that drive CRUD views.
    • Search and Filters: LiveView-powered searching and custom filtering logic.
    • Resource Actions: Support for global custom actions (e.g., exports, invitations) with optional form fields.
    • Authorization: Simple pattern-matching based authorization for CRUD and custom actions.
    • Field Types: Built-in support for Text, Number, Date, Upload, etc., with extensibility.
    • Associations: Native handling of HasOne, BelongsTo, and HasMany(Through) associations.
    • Metrics: Ability to display data insights like sums or averages.
  2. What is Backpex?

    develop

    Backpex is a highly customizable administration panel designed specifically for Phoenix LiveView applications. It enables developers to rapidly build CRUD (Create, Read, Update, Delete) interfaces for existing data by using configurable LiveResources.

    Key characteristics include:

    • Seamless Integration: Works directly within your existing Phoenix LiveView application.
    • Rapid Development: Designed to set up administration panels in hours rather than days.
    • High Customizability: Extensible via custom layouts, views, field types, and filters.
  3. How filter validation works in Backpex

    develop

    Backpex uses Ecto schemaless changesets to validate URL parameters before they are applied to database queries. This process ensures type safety and prevents malformed data from causing crashes.

    The validation lifecycle:

    1. Builds a Changeset: Creates an Ecto schemaless changeset from URL parameters.
    2. Casts Values: Converts string values to the appropriate types defined in your type/1 callback.
    3. Runs Validations: Applies custom logic defined in your changeset/3 callback.
    4. Extracts Valid Values: Only filters that pass all validations are applied to the query.
    5. Shows Errors: Invalid filters are not applied to the query; instead, the UI displays inline validation errors and shows unfiltered results for that attribute.

    If validation fails, the filter badge will not appear, and the input will show an error state.

  4. How page validation and clamping work

    develop

    Backpex uses a two-phase approach to handle pagination requests and ensure users stay within valid data ranges:

    1. Initial validation: The page parameter is checked to ensure it is a positive integer. If it is a negative number or a non-integer, it falls back to 1.
    2. Page clamping: After calculating the total number of items (which requires a database query with current filters), Backpex clamps the page number to the valid range [1, total_pages]. If a user requests a page number that exceeds the total pages (e.g., ?page=999), they are automatically redirected to the last available page.
  5. Understand custom filter validation behavior

    develop

    When a user provides an invalid value that fails the changeset/3 validation:

    1. The filter displays an error state in the UI.
    2. The filter is not applied to the database query.
    3. The results shown will be the unfiltered data for that specific attribute.
    4. The invalid value remains in the form so the user can correct it.
  6. Communicate with GenServers

    develop

    Choose between synchronous and asynchronous communication based on your requirements for back-pressure and reliability:

    • GenServer.call/3: Use for synchronous requests where you expect a reply. This provides back-pressure.
    • GenServer.cast/2: Use for fire-and-forget messages where no reply is needed.
    • Recommendation: When in doubt, use call over cast to ensure back-pressure. Always set appropriate timeouts for call/3 operations.
  7. Implement a MultiSelect Filter

    develop

    Use Backpex.Filters.MultiSelect for multi-value dropdowns with checkboxes. The default query/4 implementation performs a WHERE field IN values query.

    Implementation details:

    • Implement prompt/0 using @impl Backpex.Filters.Select.
    • Implement options/1 using @impl Backpex.Filters.MultiSelect.
    • options/1 should return a list of {label, value} tuples.
  8. Implement on_mount hooks in LiveResource

    develop

    In v0.13, LiveResource is no longer a LiveView directly; it has been split into dedicated LiveViews for Index, Form, and Show. Consequently, you cannot define handle_event/3, handle_info/2, or handle_params/3 directly in your LiveResource module.

    To attach custom logic, use the on_mount option in your use Backpex.LiveResource macro. You must:

    1. Define an on_mount callback.
    2. Use Phoenix.LiveView.attach_hook/4 within that callback to attach your custom event handlers.
    3. Halt custom events to prevent them from interfering with Backpex.
    4. Provide a catch-all handle_event at the end of your module to ensure Backpex can still receive its internal events.
    use Backpex.LiveResource,
      ...,
      on_mount: {__MODULE__, :my_hook}
    
    def on_mount(:my_hook, _params, _session, socket) do
      socket = Phoenix.LiveView.attach_hook(socket, :handle_event_callback, :handle_event, &handle_event/3)
    
      {:cont, socket}
    end
    
    def handle_event("my-event", _params_, socket) do
      # Do stuff
    
      # Make sure to halt as Backpex won't handle these events.
      {:halt, socket}
    end
    
    # Make sure to add a catch all event at the end. Otherwise Backpex won't receive internal events.
    def handle_event(_event_, _params_, socket) do
      {:cont, socket}
    end
  9. Compare Resource Actions and Item Actions

    develop

    It is important to distinguish between Resource Actions and Item Actions:

    AspectResource ActionItem Action
    ScopeWhole resourceSelected items
    UISlide-over formModal dialog
    Callbackstitle/0, label/0, handle/2icon/2, label/2, handle/3
    FormAlways has fieldsOptional
    LocationIndex toolbar onlyRow, index toolbar, show page
  10. Understand how Backpex filters work

    develop

    Filters in Backpex are used to narrow down data displayed in a LiveResource index view based on specific criteria. They operate through a lifecycle that ensures data integrity and prevents application crashes:

    1. URL Parameters: Filter values are extracted from URL query parameters (e.g., ?filters[status]=active).
    2. Type Casting: String values from the URL are cast to appropriate types like integers or dates.
    3. Validation: Values are validated using Ecto changesets.
    4. Query Application: Only filters that pass validation are applied to the database query.
    5. Error Handling: If a filter is invalid, it is not applied to the query. Instead, the user sees unfiltered results for that attribute, and an inline error is displayed in the UI to provide feedback without crashing the page.
  11. Use LiveResource hooks to react to item changes

    develop

    Backpex provides hooks that are triggered after an item has been modified in the database. You can implement these hooks to perform side effects (like sending notifications, updating caches, or logging) following a database change.

    Available hooks:

    • on_item_created/2: Called after an item is created.
    • on_item_updated/2: Called after an item is updated.
    • on_item_deleted/2: Called after an item is deleted.

    Important: These hooks are executed after the changes have been persisted to the database.

    # Example of implementing an on_item_created hook
    @impl Backpex.LiveResource
    def on_item_created(socket, item) do
        # perform side effects here
        socket
    end