### Real-World Example: Custom Header with Card Mode Source: https://github.com/gurujada/live_table/blob/master/docs/configuration.md An example demonstrating a custom header and card mode configuration for a college counselling interface. ```elixir # table_options with custom header def table_options do %{ mode: :card, card_component: &CounsellingWeb.CollegeComponent.college_component/1, custom_header: {CounsellingWeb.CollegeLive.CustomHeader, :custom_header} } end ``` -------------------------------- ### Install Typst on Ubuntu/Debian Source: https://github.com/gurujada/live_table/blob/master/docs/api/exports.md Steps to download, extract, and install the Typst binary on Ubuntu or Debian systems. ```bash # Download latest release wget https://github.com/typst/typst/releases/latest/download/typst-x86_64-unknown-linux-musl.tar.xz tar -xf typst-x86_64-unknown-linux-musl.tar.xz sudo mv typst-x86_64-unknown-linux-musl/typst /usr/local/bin/ ``` -------------------------------- ### Install LiveTable Source: https://github.com/gurujada/live_table/blob/master/README.md Run this command in your terminal to install the LiveTable dependency and assets. ```bash mix deps.get && mix live_table.install ``` -------------------------------- ### Install Typst for PDF Exports (Ubuntu/Debian) Source: https://github.com/gurujada/live_table/blob/master/docs/installation.md Install Typst on Ubuntu/Debian systems by downloading the binary and placing it in your PATH. ```bash wget https://github.com/typst/typst/releases/latest/download/typst-x86_64-unknown-linux-musl.tar.xz tar -xf typst-x86_64-unknown-linux-musl.tar.xz sudo mv typst-x86_64-unknown-linux-musl/typst /usr/local/bin/ ``` -------------------------------- ### Install Typst for PDF Exports Source: https://github.com/gurujada/live_table/blob/master/docs/troubleshooting.md Install the Typst typesetting system to enable PDF export functionality. Follow the instructions for your operating system and verify the installation. ```bash # macOS brew install typst ``` ```bash # Ubuntu/Debian wget https://github.com/typst/typst/releases/latest/download/typst-x86_64-unknown-linux-musl.tar.xz tar -xf typst-x86_64-unknown-linux-musl.tar.xz sudo mv typst-x86_64-unknown-linux-musl/typst /usr/local/bin/ ``` ```bash # Verify installation typst --version ``` -------------------------------- ### Application-Wide Configuration Example Source: https://github.com/gurujada/live_table/blob/master/docs/api/table-options.md Shows how to set default options for all LiveTables within an application by configuring the `:live_table` application. ```APIDOC ## Application-Wide Configuration Set defaults for all tables in your application: ```elixir # config/config.exs config :live_table, defaults: %{ pagination: %{ enabled: true, sizes: [20, 50, 100] }, sorting: %{ default_sort: [inserted_at: :desc] }, exports: %{ enabled: true, formats: [:csv, :pdf] } } ``` ``` -------------------------------- ### Verify Typst Installation Source: https://github.com/gurujada/live_table/blob/master/docs/installation.md Check if Typst is installed correctly by running the version command. ```bash typst --version ``` -------------------------------- ### Install LiveTable Generator Source: https://github.com/gurujada/live_table/blob/master/usage_rules.md Commands to install the LiveTable generator. Use the `--oban` flag if you intend to use Oban for export functionality. ```bash mix live_table.install ``` ```bash mix live_table.install --oban # With Oban for exports ``` -------------------------------- ### Run Oban Migrations Source: https://github.com/gurujada/live_table/blob/master/docs/installation.md After configuring Oban, run its installation task and Ecto migrations to set up the necessary database tables. ```bash mix oban.install mix ecto.migrate ``` -------------------------------- ### Simple Table Setup with LiveResource Source: https://github.com/gurujada/live_table/blob/master/docs/README.md Use this pattern to set up a simple table by directly referencing your Ecto schema. ```elixir use LiveTable.LiveResource, schema: YourApp.Product ``` -------------------------------- ### Run LiveTable Installer Source: https://github.com/gurujada/live_table/blob/master/docs/generators/live_table.install.md Execute the `mix live_table.install` command to automatically configure your Phoenix application for LiveTable. ```bash mix live_table.install ``` -------------------------------- ### Run LiveTable Installer with Oban Source: https://github.com/gurujada/live_table/blob/master/docs/generators/live_table.install.md Use the `--oban` flag with `mix live_table.install` to configure Oban for CSV/PDF exports. ```bash mix live_table.install --oban ``` -------------------------------- ### Custom Query Data Provider Setup Source: https://github.com/gurujada/live_table/blob/master/usage_rules.md When using custom queries, ensure a `data_provider` is assigned in the `mount/3` function. This example shows the missing assignment, which leads to errors. ```elixir # Wrong - Custom query without data provider use LiveTable.LiveResource def fields do [complex_field: %{label: "Complex"}] end # Missing: data_provider assignment in mount/3 ``` -------------------------------- ### E-commerce Product Filters Example Source: https://github.com/gurujada/live_table/blob/master/docs/api/filters.md An example demonstrating how to set up filters for an e-commerce product listing, including active products, price range, category search, low stock alerts, and new arrivals. ```elixir def filters do [ # Active products toggle active: Boolean.new(:active, "active", %{ label: "Show Active Products Only", condition: dynamic([p], p.active == true) }), # Price range slider price_range: Range.new(:price, "price_range", %{ type: :number, label: "Price Range", unit: "$", min: 0, max: 2000, step: 25, default_min: 0, default_max: 500 }), # Category dropdown with search category: Select.new({:categories, :name}, "category", %{ label: "Category", placeholder: "Search categories...", options_source: {Shop.Catalog, :search_categories, []} }), # Stock level toggle low_stock: Boolean.new(:stock_quantity, "low_stock", %{ label: "Low Stock Alert (< 10 items)", condition: dynamic([p], p.stock_quantity < 10 and p.stock_quantity > 0) }), # Recently added toggle new_arrivals: Boolean.new(:inserted_at, "new_arrivals", %{ label: "New Arrivals (Last 30 Days)", condition: dynamic([p], p.inserted_at >= ago(30, "day") ) }) ] end ``` -------------------------------- ### Start Oban in Application Supervision Tree Source: https://github.com/gurujada/live_table/blob/master/docs/generators/live_table.install.md If Oban is configured for exports, add it to your application's supervision tree in `lib/your_app/application.ex` to ensure it starts correctly. ```elixir children = [ # ... other children {Oban, Application.fetch_env!(:your_app, Oban)} ] ``` -------------------------------- ### Install Typst for PDF Exports (macOS) Source: https://github.com/gurujada/live_table/blob/master/docs/installation.md Install Typst using Homebrew on macOS. This is a prerequisite for PDF export functionality. ```bash brew install typst ``` -------------------------------- ### Basic Table Setup with LiveResource Source: https://context7.com/gurujada/live_table/llms.txt Set up a data table using LiveTable.LiveResource with an Ecto schema. Define fields, filters, and custom renderers for columns. ```elixir defmodule YourAppWeb.ProductLive.Index do use YourAppWeb, :live_view use LiveTable.LiveResource, schema: YourApp.Catalog.Product def fields do [ id: %{label: "ID", sortable: true}, name: %{label: "Product Name", sortable: true, searchable: true}, sku: %{label: "SKU", sortable: true, searchable: true}, price: %{label: "Price", sortable: true, renderer: &format_price/1}, stock_quantity: %{label: "Stock", sortable: true}, active: %{label: "Status", sortable: true, renderer: &format_status/1} ] end def filters do [ active_only: Boolean.new(:active, "active", %{ label: "Active Products Only", condition: dynamic([p], p.active == true) }), price_range: Range.new(:price, "price_range", %{ type: :number, label: "Price Range", unit: "$", min: 0, max: 1000, step: 10 }), low_stock: Boolean.new(:stock_quantity, "low_stock", %{ label: "Low Stock (< 10)", condition: dynamic([p], p.stock_quantity < 10) }) ] end defp format_price(price) do assigns = %{price: price} ~H""" $<%= :erlang.float_to_binary(@price, decimals: 2) %> """ end defp format_status(active) do assigns = %{active: active} ~H""" <%= if @active, do: "Active", else: "Inactive" %> """ end end ``` -------------------------------- ### Run Project Tests Source: https://github.com/gurujada/live_table/blob/master/docs/troubleshooting.md Execute your project's test suite to verify the setup and ensure that all components are functioning as expected. This is a fundamental step in confirming a correct configuration. ```bash # Run tests to verify setup mix test ``` -------------------------------- ### Minimal LiveTable Verification - LiveView Module Source: https://github.com/gurujada/live_table/blob/master/docs/installation.md Create a minimal LiveView module to test your LiveTable installation. This example defines fields for ID and email. ```elixir defmodule YourAppWeb.TestLive do use YourAppWeb, :live_view use LiveTable.LiveResource, schema: YourApp.User def fields do [ id: %{label: "ID", sortable: true}, email: %{label: "Email", sortable: true, searchable: true} ] end def filters, do: [] end ``` -------------------------------- ### Environment-Specific Configuration (Production) Source: https://github.com/gurujada/live_table/blob/master/docs/api/table-options.md Example of Live Table configuration for the production environment, with optimized pagination, enabled exports, and a longer search debounce. ```elixir # config/prod.exs config :live_table, defaults: %{ pagination: %{ sizes: [25, 50, 100], default_size: 50 }, exports: %{ enabled: true, formats: [:csv, :pdf] }, search: %{debounce: 500} # Longer debounce for production # debug set to :off by default } ``` -------------------------------- ### Per-Table Configuration Example Source: https://github.com/gurujada/live_table/blob/master/docs/api/table-options.md Demonstrates how to override LiveTable settings for a specific table by implementing the `table_options/0` function within a LiveView module. ```APIDOC ## Per-Table Configuration Override settings for specific tables by implementing `table_options/0`: ```elixir defmodule YourAppWeb.ProductLive.Index do use YourAppWeb, :live_view use LiveTable.LiveResource, schema: YourApp.Product def table_options do %{ pagination: %{ enabled: true, sizes: [10, 25, 50] }, sorting: %{ default_sort: [name: :asc] }, mode: :table } end end ``` ``` -------------------------------- ### Environment-Specific Configuration (Development) Source: https://github.com/gurujada/live_table/blob/master/docs/api/table-options.md Example of Live Table configuration for the development environment, overriding defaults with smaller pagination and disabled exports. ```elixir # config/dev.exs config :live_table, defaults: %{ pagination: %{ sizes: [5, 10, 15], # Smaller pages for development default_size: 5 }, exports: %{enabled: false}, # Disable exports in development debug: :query # Show queries in development } ``` -------------------------------- ### Install Igniter Dependency Source: https://github.com/gurujada/live_table/blob/master/docs/generators/live_table.gen.live.md Add the `:igniter` dependency to your `mix.exs` file to use the LiveTable generator. ```elixir {:igniter, "~> 0.7", only: :dev, runtime: false} ``` -------------------------------- ### Order Report LiveView Setup Source: https://github.com/gurujada/live_table/blob/master/docs/examples/complex-queries.md Sets up a LiveView to display an order report using LiveTable. Requires `LiveTable.LiveResource` and defines data provider, fields, and filters. ```elixir defmodule YourAppWeb.OrderReportLive.Index do use YourApp, :live_view use LiveTable.LiveResource def mount(_params, _session, socket) do socket = assign(socket, :data_provider, {YourApp.Reports, :order_details, []}) {:ok, socket} end def fields do [ order_id: %{label: "Order #", sortable: true}, customer_name: %{label: "Customer", sortable: true, searchable: true}, customer_email: %{label: "Email", sortable: true, searchable: true}, product_count: %{label: "Items", sortable: true}, total_amount: %{label: "Total", sortable: true, renderer: &render_currency/1}, order_date: %{label: "Order Date", sortable: true, renderer: &render_date/1}, shipping_method: %{ label: "Shipping", sortable: true, assoc: {:shipping, :method} }, status: %{label: "Status", sortable: true, renderer: &render_status/1}, days_since_order: %{label: "Age (Days)", sortable: true, renderer: &render_days/1} ] end def filters do [ status: Select.new({:orders, :status}, "status", %{ label: "Order Status", options: [ %{label: "Pending", value: ["pending"]}, %{label: "Processing", value: ["processing"]}, %{label: "Shipped", value: ["shipped"]}, %{label: "Delivered", value: ["delivered"]} ] }), order_value: Range.new(:total_amount, "order_value", %{ type: :number, label: "Order Value", min: 0, max: 10000, step: 100 }), customer_type: Select.new({:customers, :type}, "customer_type", %{ label: "Customer Type", options: [ %{label: "Individual", value: ["individual"]}, %{label: "Business", value: ["business"]} ] }), recent_orders: Boolean.new(:order_date, "recent", %{ label: "Last 30 Days", condition: dynamic([o, customers: c, shipping: s], o.inserted_at >= ago(30, "day")) }) ] end defp render_currency(amount) do assigns = %{amount: amount} ~H""" $<.erlang.float_to_binary(@amount, decimals: 2) %> """ end defp render_date(date) do assigns = %{date: date} ~H""" <%= Calendar.strftime(@date, "%b %d, %Y") %> """ end defp render_status(status) do assigns = %{status: status} ~H""" "bg-yellow-100 text-yellow-700" "processing" -> "bg-blue-100 text-blue-700" "shipped" -> "bg-purple-100 text-purple-700" "delivered" -> "bg-green-100 text-green-700" end ]}> <%= String.Capitalize(@status) %> """ end defp render_days(days) do assigns = %{days: days} ~H""" 30, do: "text-red-600", else: "text-gray-600") ]}> <%= @days %> days """ end end ``` -------------------------------- ### User Management Filters Example Source: https://github.com/gurujada/live_table/blob/master/docs/api/filters.md An example for user management filters, including active users toggle, registration date range, role selection dropdown, and email verification status. ```elixir def filters do [ # Active users active_users: Boolean.new(:active, "active", %{ label: "Active Users Only", condition: dynamic([u], u.active == true) }), # Registration date range signup_date: Range.new(:inserted_at, "signup_range", %{ type: :date, label: "Registration Date", min: ~D[2020-01-01], max: Date.utc_today() }), # Role selection role: Select.new(:role, "role", %{ label: "User Role", options: [ %{label: "Admin", value: ["admin"]}, %{label: "Manager", value: ["manager"]}, %{label: "User", value: ["user"]}, %{label: "Guest", value: ["guest"]} ] }), # Email verified toggle verified: Boolean.new(:email_verified_at, "verified", %{ label: "Email Verified", condition: dynamic([u], not is_nil(u.email_verified_at)) }) ] end ``` -------------------------------- ### Environment-Specific Configuration (Test) Source: https://github.com/gurujada/live_table/blob/master/docs/api/table-options.md Example of Live Table configuration for the test environment, disabling pagination and search debounce for faster test execution. ```elixir # config/test.exs config :live_table, defaults: %{ pagination: %{enabled: false}, # Show all records in tests exports: %{enabled: false}, search: %{debounce: 0} # No debounce in tests # debug set to :off by default } ``` -------------------------------- ### Seed Sample Product Data Source: https://github.com/gurujada/live_table/blob/master/docs/quick-start.md Provides an example of how to seed the database with sample product data using Ecto. This is useful for testing the LiveTable implementation. ```elixir # priv/repo/seeds.exs alias YourApp.Repo alias YourApp.Catalog.Product ``` -------------------------------- ### Order Analytics Filters Example Source: https://github.com/gurujada/live_table/blob/master/docs/api/filters.md An example demonstrating filters for order analytics, including order status, order value range, order date range, high priority orders toggle, and customer type selection. ```elixir def filters do [ # Order status status: Select.new(:status, "status", %{ label: "Order Status", options: [ %{label: "Pending", value: ["pending"]}, %{label: "Processing", value: ["processing"]}, %{label: "Shipped", value: ["shipped"]}, %{label: "Delivered", value: ["delivered"]}, %{label: "Cancelled", value: ["cancelled"]} ] }), # Order value range order_total: Range.new(:total_amount, "total_range", %{ type: :number, label: "Order Total", unit: "$", min: 0, max: 10000, step: 100 }), # Date range for order placement order_date: Range.new(:inserted_at, "order_date_range", %{ type: :date, label: "Order Date", min: Date.add(Date.utc_today(), -365), max: Date.utc_today() }), # High priority orders priority_orders: Boolean.new(:priority, "priority", %{ label: "Priority Orders Only", condition: dynamic([o], o.priority in ["high", "urgent"]) }), # Customer type (for custom queries with joins) customer_type: Select.new({:customers, :type}, "customer_type", %{ label: "Customer Type", options: [ %{label: "Individual", value: ["individual"]}, %{label: "Business", value: ["business"]}, %{label: "Enterprise", value: ["enterprise"]} ] }) ] end ``` -------------------------------- ### Inspect Ecto Queries for Performance Source: https://github.com/gurujada/live_table/blob/master/docs/troubleshooting.md Inspect Ecto queries directly to understand their performance characteristics. This example shows how to convert an Ecto query to SQL for inspection. ```elixir iex> query = YourApp.Products.list_products() iex> IO.inspect(Ecto.Adapters.SQL.to_sql(:all, YourApp.Repo, query)) ``` -------------------------------- ### Live Table Per-Table Options Override Source: https://github.com/gurujada/live_table/blob/master/docs/configuration.md Define table-specific options to override global defaults. This example shows how to customize pagination sizes, default sort order, export formats, and the display mode for a specific table. ```elixir defmodule YourAppWeb.ProductLive.Index do def table_options do %{ pagination: %{sizes: [5, 15, 30]}, sorting: %{default_sort: [name: :asc]}, exports: %{formats: [:csv]}, mode: :card, card_component: &product_card/1 } end end ``` -------------------------------- ### Verify LiveTable Schema and Data Source: https://github.com/gurujada/live_table/blob/master/docs/troubleshooting.md Check your LiveTable schema configuration and ensure data exists in the database. This example shows how to verify the schema and query data using Ecto. ```elixir use LiveTable.LiveResource, schema: YourApp.Product iex> YourApp.Repo.all(YourApp.Product) |> length() ``` -------------------------------- ### Correct LiveResource Setup in LiveView Source: https://github.com/gurujada/live_table/blob/master/docs/troubleshooting.md Ensure `LiveTable.LiveResource` is used in your LiveView module for LiveTable components to render correctly. This example shows the correct setup. ```elixir defmodule YourAppWeb.ProductLive.Index do use YourAppWeb, :live_view use LiveTable.LiveResource, schema: YourApp.Product def fields do [name: %{label: "Name"}] end end ``` -------------------------------- ### Example CSV Output Source: https://github.com/gurujada/live_table/blob/master/docs/api/exports.md This is an example of the CSV data format that LiveTable can generate, including headers and sample rows. ```csv ID,Product Name,Price,Stock,Category 1,iPhone 15 Pro,999.99,25,Electronics 2,MacBook Air,1199.99,8,Electronics 3,Wireless Mouse,45.99,50,Accessories ``` -------------------------------- ### Fetch Dependencies Source: https://github.com/gurujada/live_table/blob/master/docs/installation.md After updating mix.exs, run this command to fetch the new dependency. ```bash mix deps.get ``` -------------------------------- ### Action Component Assigns Example Source: https://github.com/gurujada/live_table/blob/master/docs/api/fields.md Access the current record within an action component using the @record assign. This example shows how to display the record's name in a 'View' link. ```elixir defp view_action(assigns) do ~H""" <.link navigate={~p"/products/#{@record.id}"}> View <%= @record.name %> """ end ``` -------------------------------- ### Basic Product Table Implementation Source: https://github.com/gurujada/live_table/blob/master/docs/examples/simple-table.md Defines fields, filters, and a status renderer for a product table. Requires `LiveTable.LiveResource` and a `YourApp.Product` schema. ```elixir defmodule YourAppWeb.ProductLive.Index do use YourAppWeb, :live_view use LiveTable.LiveResource, schema: YourApp.Product def fields do [ id: %{label: "ID", sortable: true}, name: %{label: "Product Name", sortable: true, searchable: true}, price: %{label: "Price", sortable: true}, stock_quantity: %{label: "Stock", sortable: true}, active: %{label: "Status", sortable: true, renderer: &render_status/1} ] end def filters do [ active: Boolean.new(:active, "active", %{ label: "Active Products Only", condition: dynamic([p], p.active == true) }), price_range: Range.new(:price, "price_range", %{ type: :number, label: "Price Range", min: 0, max: 1000 }) ] end defp render_status(active) do assigns = %{active: active} ~H""" <%= if @active, do: "Active", else: "Inactive" %> """ end end ``` ```html

Products

<.live_table fields={fields()} filters={filters()} options={@options} streams={@streams} />
``` -------------------------------- ### Create Transformers with Different Callbacks Source: https://github.com/gurujada/live_table/blob/master/docs/api/transformers.md Demonstrates creating transformers using function references, module/function tuples, and anonymous functions. ```elixir # Using a function reference sales_filter: Transformer.new("sales_filter", %{ query_transformer: &transform_sales_query/2 }) # Using a module and function tuple analytics_filter: Transformer.new("analytics", %{ query_transformer: {MyApp.Analytics, :transform_query} }) # Using an anonymous function custom_filter: Transformer.new("custom", %{ query_transformer: fn query, data -> # Transform query based on data query end }) ``` -------------------------------- ### Add Igniter Dependency for Installer Source: https://github.com/gurujada/live_table/blob/master/docs/installation.md If you intend to use the installer/generator tasks, add the optional Igniter dependency for development. ```elixir {:igniter, ">~ 0.7", only: :dev, runtime: false} ``` -------------------------------- ### Create Product Data Source: https://github.com/gurujada/live_table/blob/master/docs/quick-start.md Defines a list of product structs for seeding a database. Ensure Decimal is imported. ```elixir products = [ %Product{ name: "iPhone 15 Pro", description: "Latest Apple smartphone", price: Decimal.new("999.99"), stock_quantity: 25, active: true, sku: "IPHONE15PRO" }, %Product{ name: "MacBook Air M2", description: "Apple laptop with M2 chip", price: Decimal.new("1199.99"), stock_quantity: 8, active: true, sku: "MACBOOKAIR" }, %Product{ name: "Wireless Mouse", description: "Ergonomic wireless mouse", price: Decimal.new("45.99"), stock_quantity: 50, active: true, sku: "WMOUSE01" }, %Product{ name: "USB Cable", description: "High-quality USB-C cable", price: Decimal.new("24.99"), stock_quantity: 3, active: true, sku: "USBCABLE" }, %Product{ name: "Discontinued Phone", description: "No longer available", price: Decimal.new("299.99"), stock_quantity: 0, active: false, sku: "OLDPHONE" } ] Enum.each(products, &Repo.insert!/1) ``` -------------------------------- ### Restart Phoenix Server Source: https://github.com/gurujada/live_table/blob/master/docs/generators/live_table.install.md After completing the installation and manual configuration steps, restart your Phoenix server to apply all changes. ```bash mix phx.server ``` -------------------------------- ### Live Table Complete Configuration Reference Source: https://github.com/gurujada/live_table/blob/master/docs/configuration.md A comprehensive list of all available configuration options for Live Table, including detailed settings for pagination, sorting, exports, search, and general table behavior. ```elixir config :live_table, defaults: %{ pagination: %{ enabled: true, sizes: [10, 25, 50], default_size: 10, max_per_page: 50 }, sorting: %{ enabled: true, default_sort: [id: :asc] }, exports: %{ enabled: true, formats: [:csv, :pdf] }, search: %{ enabled: true, debounce: 300, placeholder: "Search..." }, max_filters: 3, mode: :table, use_streams: true } ``` -------------------------------- ### Minimal LiveTable Verification - Router Configuration Source: https://github.com/gurujada/live_table/blob/master/docs/installation.md Add a route in your router to access the minimal LiveView created for testing the LiveTable installation. ```elixir live "/test", TestLive ``` -------------------------------- ### Configure Data Handling with Streams or Assigns Source: https://github.com/gurujada/live_table/blob/master/docs/configuration.md Choose between using Phoenix LiveView streams (recommended for performance) or traditional assigns for data handling. Adjust the `use_streams` option accordingly. ```elixir # Default: Use Phoenix LiveView streams (recommended) use_streams: true # Default ``` ```elixir # Alternative: Use traditional assigns use_streams: false ``` -------------------------------- ### Incorrectly Mixing Patterns with LiveTable Source: https://github.com/gurujada/live_table/blob/master/usage_rules.md Avoid using the 'schema:' parameter with custom queries. This example shows the incorrect usage that should be removed. ```elixir # WRONG - Don't do this use LiveTable.LiveResource, schema: User # Remove this line def mount(_params, _session, socket) do socket = assign(socket, :data_provider, {MyApp.Users, :complex_query, []}) {:ok, socket} end ``` -------------------------------- ### Define Filters with Transformers Source: https://github.com/gurujada/live_table/blob/master/docs/api/transformers.md Example of defining regular filters alongside a transformer that modifies the entire query using a function reference. ```elixir def filters do [ # Regular filters active: Boolean.new(:active, "active", %{ label: "Active Only", condition: dynamic([p], p.active == true) }), # Transformer - can modify entire query sales_performance: Transformer.new("sales_performance", %{ query_transformer: &apply_sales_filter/2 }) ] end defp apply_sales_filter(query, filter_data) do case filter_data do %{"period" => period, "min_sales" => min_sales} -> from p in query, join: s in Sales, on: s.product_id == p.id, where: s.period == ^period and s.total >= ^min_sales, group_by: p.id _ -> query end end ``` -------------------------------- ### Configure LiveTable with Data Provider and Filters Source: https://context7.com/gurujada/live_table/llms.txt Mount the LiveView and assign the data provider. Define filters using Select.new and Boolean.new, specifying conditions for dynamic filtering. ```elixir defmodule YourAppWeb.OrderReportLive.Index do use YourAppWeb, :live_view use LiveTable.LiveResource def mount(_params, _session, socket) do socket = assign(socket, :data_provider, {YourApp.Reports, :order_details, []}) {:ok, socket} end def filters do [ status: Select.new({:orders, :status}, "status", %{ label: "Order Status", options: [ %{label: "Pending", value: ["pending"]}, %{label: "Shipped", value: ["shipped"]}, %{label: "Delivered", value: ["delivered"]} ] }), customer_type: Select.new({:customers, :type}, "customer_type", %{ label: "Customer Type", options: [ %{label: "Individual", value: ["individual"]}, %{label: "Business", value: ["business"]} ] }), recent_orders: Boolean.new(:order_date, "recent", %{ label: "Last 30 Days", condition: dynamic([o, customers: c, shipping: s], o.inserted_at >= ago(30, "day")) }) ] end end ``` -------------------------------- ### LiveTable Actions Configuration Source: https://github.com/gurujada/live_table/blob/master/docs/overview.md Configures actions for LiveTable rows as an optional component assign. This example shows how to define a 'view' action. ```elixir <.live_table ... actions={%{label: "Actions", items: [view: &view_action/1]}} /> ``` -------------------------------- ### LiveTable Configuration Source: https://github.com/gurujada/live_table/blob/master/usage_rules.md Configure the LiveTable repository and pubsub in your 'config/config.exs'. Oban configuration is only needed if using export functionality. ```elixir # In config/config.exs config :live_table, repo: YourApp.Repo, pubsub: YourApp.PubSub # Add Oban config only if using exports # config :your_app, Oban, # repo: YourApp.Repo, # queues: [exports: 10] ``` -------------------------------- ### Responsive Card Grid Configuration Source: https://github.com/gurujada/live_table/blob/master/docs/api/table-options.md Configure Live Table for card mode, implying a responsive grid layout for cards. Requires a `card_component` to be defined. ```elixir def table_options do %{ mode: :card, card_component: &responsive_card/1 } end ``` -------------------------------- ### Basic Card Layout Configuration Source: https://github.com/gurujada/live_table/blob/master/docs/api/table-options.md Configure Live Table to use card mode with a simple custom card component for displaying records. ```elixir def table_options do %{ mode: :card, card_component: &simple_card/1 } end defp simple_card(assigns) do ~H"""

<%= @record.name %>

<%= @record.description %>

""" end ``` -------------------------------- ### Boolean Filter Configuration Source: https://github.com/gurujada/live_table/blob/master/usage_rules.md Example of configuring a boolean filter for LiveTable, specifying the field name, parameter name, label, and the dynamic condition. ```elixir Boolean.new(:field_name, "param_name", %{ label: "Filter Label", condition: dynamic([alias], alias.field_name > 0) }) ``` -------------------------------- ### Run Database Migrations Source: https://github.com/gurujada/live_table/blob/master/docs/generators/live_table.gen.live.md Apply database schema changes after generation using the mix ecto.migrate command. ```bash mix ecto.migrate ``` -------------------------------- ### Create Focused Transformers Source: https://github.com/gurujada/live_table/blob/master/docs/api/transformers.md Defines transformers with a single responsibility. This example shows creating separate transformers for sales filtering and performance metrics calculation. ```elixir # ✅ Good: Single responsibility sales_filter: Transformer.new("sales", %{ query_transformer: &add_sales_filtering/2 }) metrics_calculator: Transformer.new("metrics", %{ query_transformer: &add_performance_metrics/2 }) # ❌ Avoid: Doing everything in one transformer ``` -------------------------------- ### Geographic Region Filter Transformer Source: https://github.com/gurujada/live_table/blob/master/docs/api/transformers.md Example of a transformer using a module/function tuple to filter data by geographic region, with an option to include nearby regions. ```elixir def filters do [ region_analysis: Transformer.new("region_analysis", %{ query_transformer: {MyApp.Geography, :filter_by_region} }) ] end # In your context module defmodule MyApp.Geography do def filter_by_region(query, %{"region" => region, "include_nearby" => "true"}) do from p in query, join: l in Location, on: l.id == p.location_id, join: r in Region, on: r.id == l.region_id, left_join: nr in Region, on: nr.parent_id == r.id, where: r.name == ^region or nr.name == ^region, preload: [location: [region: :parent]] end def filter_by_region(query, %{"region" => region}) do from p in query, join: l in Location, on: l.id == p.location_id, join: r in Region, on: r.id == l.region_id, where: r.name == ^region end def filter_by_region(query, _), do: query end ``` -------------------------------- ### Preview Query Before Fetching Source: https://github.com/gurujada/live_table/blob/master/docs/api/table-options.md Set `debug` to `:query` to preview the fully built query before it is fetched from the database. This is useful for debugging query construction. ```elixir debug: :query ``` -------------------------------- ### Run Database Seeds Source: https://github.com/gurujada/live_table/blob/master/docs/quick-start.md Executes the database seeding script to populate the database with initial data. ```bash mix run priv/repo/seeds.exs ``` -------------------------------- ### Inspect Effective Live Table Configuration Source: https://github.com/gurujada/live_table/blob/master/docs/api/table-options.md Use `get_merged_table_options/0` to retrieve the combined configuration and `IO.inspect/2` to log it. This is useful for debugging and verifying that your options are applied correctly. ```elixir # Check effective configuration def mount(_params, _session, socket) do effective_config = get_merged_table_options() IO.inspect(effective_config, label: "Table Config") {:ok, socket} end ``` -------------------------------- ### Check LiveTable Version Source: https://github.com/gurujada/live_table/blob/master/docs/troubleshooting.md Verify the installed version of the LiveTable dependency using the `mix deps` command. This is a quick check to ensure you are using the expected version. ```bash # Check LiveTable version mix deps | grep live_table ``` -------------------------------- ### Configure Select Filters with Dynamic Options Source: https://github.com/gurujada/live_table/blob/master/docs/api/filters.md Sets up Select filters that fetch options dynamically from the database using `options_source`. This is useful for categories and suppliers. ```elixir def filters do [ category: Select.new({:categories, :name}, "category", %{ label: "Product Category", options_source: {YourApp.Catalog, :search_categories, []} }), supplier: Select.new({:suppliers, :name}, "supplier", %{ label: "Supplier", placeholder: "Search suppliers...", options_source: {YourApp.Suppliers, :search_suppliers, []} }) ] end ``` -------------------------------- ### Basic Boolean Filter Usage Source: https://github.com/gurujada/live_table/blob/master/docs/api/filters.md Implement basic Boolean filters as checkboxes for true/false conditions. This example shows filters for 'active' status and 'in_stock' quantity. ```elixir def filters do [ active: Boolean.new(:active, "active", %{ label: "Active Products Only", condition: dynamic([p], p.active == true) }), in_stock: Boolean.new(:stock_quantity, "in_stock", %{ label: "In Stock", condition: dynamic([p], p.stock_quantity > 0) }) ] end ``` -------------------------------- ### Create Select Filters with Static and Dynamic Options Source: https://context7.com/gurujada/live_table/llms.txt Use Select.new to create dropdown filters. Options can be static or dynamically fetched from the database using an options_source. Ensure dynamic options return tuples. ```elixir def filters do [ # Static options status: Select.new(:status, "status", %{ label: "Order Status", options: [ %{label: "Pending", value: ["pending"]}, %{label: "Processing", value: ["processing"]}, %{label: "Shipped", value: ["shipped"]}, %{label: "Delivered", value: ["delivered"]} ] }), # Filter by string field (not just ID) priority: Select.new(:priority, "priority", %{ label: "Priority Level", options: [ %{label: "Low", value: "low"}, %{label: "Medium", value: "medium"}, %{label: "High", value: "high"} ] }), # Dynamic options from database category: Select.new({:categories, :name}, "category", %{ label: "Product Category", placeholder: "Search categories...", options_source: {YourApp.Catalog, :search_categories, []} }), # Custom option template supplier: Select.new({:suppliers, :name}, "supplier", %{ label: "Supplier", options_source: {YourApp.Suppliers, :search_suppliers, []}, option_template: &custom_supplier_template/1 }) ] end ``` ```elixir defmodule YourApp.Catalog do def search_categories(search_text \ "") do Category |> where([c], ilike(c.name, ^"%#{search_text}%")) |> select([c], {c.name, [c.id, c.description]}) |> Repo.all() end end ``` -------------------------------- ### Verify Specific Live Table Options Source: https://github.com/gurujada/live_table/blob/master/docs/api/table-options.md Define and inspect specific table options using `IO.inspect/2`. This helps in debugging individual configuration settings like pagination and sorting. ```elixir # Verify specific options def table_options do config = %{ pagination: %{enabled: true, sizes: [10, 25]}, sorting: %{default_sort: [name: :asc]} } IO.inspect(config, label: "Table Options") config end ``` -------------------------------- ### Custom Query Setup for LiveTable Source: https://github.com/gurujada/live_table/blob/master/docs/README.md Configure LiveTable to use a custom data provider module and query function. This is useful for complex data retrieval logic. ```elixir assign(socket, :data_provider, {YourApp.Products, :complex_query, []}) ``` -------------------------------- ### Configure Live Table for Large Datasets Source: https://github.com/gurujada/live_table/blob/master/docs/api/table-options.md Adjust pagination and search debounce for better performance with large datasets. Use smaller page sizes and a longer debounce for search. ```elixir def table_options do %{ pagination: %{ enabled: true, sizes: [25, 50] # Smaller page sizes }, search: %{ debounce: 500 # Longer debounce } } end ``` -------------------------------- ### Configure LiveTable with Custom Query and Joins Source: https://github.com/gurujada/live_table/blob/master/docs/quick-start.md Sets up a LiveView to display data from a custom Ecto query involving joins. The `data_provider` function and `fields` definition must align with the query's output. ```elixir defmodule YourAppWeb.OrderReportLive.Index do use YourAppWeb, :live_view use LiveTable.LiveResource def mount(_params, _session, socket) do # Assign your custom data provider function socket = assign(socket, :data_provider, {YourApp.Orders, :list_with_products, []}) {:ok, socket} end def fields do [ order_id: %{label: "Order #", sortable: true}, customer_email: %{label: "Customer", sortable: true, searchable: true}, total_amount: %{label: "Total", sortable: true}, # Reference the alias used in your custom query product_name: %{ label: "Product", sortable: true, searchable: true, assoc: {:order_items, :product_name} }, order_date: %{label: "Date", sortable: true} ] end def filters do [ status: Select.new({:orders, :status}, "status", %{ label: "Order Status", options: [ %{label: "Pending", value: ["pending"]}, %{label: "Shipped", value: ["shipped"]}, %{label: "Delivered", value: ["delivered"]} ] }), amount_range: Range.new(:total_amount, "amount_range", %{ type: :number, label: "Order Amount", min: 0, max: 5000 }) ] end end ``` -------------------------------- ### Document Complex Business Logic Source: https://github.com/gurujada/live_table/blob/master/docs/api/transformers.md Includes comments to document complex business logic within a transformer. This example outlines requirements for a 'Premium Customer Analysis' transformer. ```elixir defp apply_complex_business_logic(query, filter_data) do # This transformer implements the "Premium Customer Analysis" requirements: # 1. Customers with orders > $1000 in last 6 months # 2. Include loyalty points and tier information # 3. Calculate lifetime value with predictive scoring case filter_data do %{"analysis_type" => "premium"} -> # Implementation here... end end ``` -------------------------------- ### Environment-Specific LiveTable Configuration Source: https://github.com/gurujada/live_table/blob/master/docs/configuration.md Illustrates how to configure LiveTable settings differently for development and production environments using `config/dev.exs` and `config/prod.exs`. This allows for tailored defaults like pagination sizes and export enablement. ```elixir # config/dev.exs config :live_table, defaults: %{ pagination: %{sizes: [5, 10]}, exports: %{enabled: false} } ``` ```elixir # config/prod.exs config :live_table, defaults: %{ pagination: %{sizes: [25, 50, 100]}, exports: %{enabled: true} } ``` -------------------------------- ### Advanced Boolean Filter Conditions Source: https://github.com/gurujada/live_table/blob/master/docs/api/filters.md Create complex Boolean filter conditions, including those involving multiple criteria or fields from joined tables. Examples for 'premium_products' and 'verified_suppliers'. ```elixir def filters do [ # Complex condition with multiple criteria premium_products: Boolean.new(:price, "premium", %{ label: "Premium Products (>$500 & Featured)", condition: dynamic([p], p.price > 500 and p.featured == true) }), # Condition using joined tables (for custom queries) verified_suppliers: Boolean.new({:suppliers, :verified}, "verified", %{ label: "Verified Suppliers Only", condition: dynamic([p, suppliers: s], s.verified == true and s.active == true) }) ] end ``` -------------------------------- ### Filter Simple Schema Fields Source: https://github.com/gurujada/live_table/blob/master/docs/api/filters.md Reference schema fields directly for single-table queries when defining filters. Examples for Boolean and Range filters on 'Product.active' and 'Product.price' respectively. ```elixir # Filter on Product.active field active_filter: Boolean.new(:active, "active", %{...}) # Filter on Product.price field price_filter: Range.new(:price, "price_range", %{...}) ``` -------------------------------- ### Define LiveTable Filters Source: https://github.com/gurujada/live_table/blob/master/docs/api/filters.md Define filters for LiveTable using a keyword list where each key maps to a filter struct. This example shows Boolean, Range, and Select filters. ```elixir def filters do [ active: Boolean.new(:active, "active", %{ label: "Active Only", condition: dynamic([p], p.active == true) }), price_range: Range.new(:price, "price_range", %{ type: :number, label: "Price Range", min: 0, max: 1000 }), category: Select.new({:category, :name}, "category", %{ label: "Category", options: [ %{label: "Electronics", value: ["electronics"]}, %{label: "Books", value: ["books"]} ] }) ] end ``` -------------------------------- ### Create a Select Filter Source: https://github.com/gurujada/live_table/blob/master/usage_rules.md Use `Select.new` to create a filter with predefined options. Configure the field, parameter name, label, and the list of options with their display labels and underlying values. ```elixir Select.new({:table_alias, :field_name}, "param_name", %{ label: "Select Label", options: [ %{label: "Display", value: ["actual_value"]}, %{label: "All Active", value: ["active", "pending"]} ] }) ```