Backpex - a highly customizable admin panel for Phoenix LiveView applications

Hey!

I can see the problem that providing all the information can be tedious at first, but I also think that hiding the live resource configuration behind another module is not perfect either. Especially when it comes to supporting multiple data sources, like Ecto or Ash.

The setup is not that easy anyway, and creating another abstraction (live resources are already an abstraction for resources) makes it even more complicated.

I really appreciate your work and ideas to simplify the setup, but I guess we will not add such an auto live resources to the core at the moment. We are open to an add-on package if you need this feature and want to maintain such an automatic resource generation.

When it comes to making setup easier, I’d like to see Mix tasks that do the resource introspection and automatically generate live resources for you. The advantage of a Mix task is that we’d simplify the setup, but end up with the same configuration (both manually and programmatically via running a mix task).

Looking forward to hearing your thoughts!

1 Like

I understand. I have no interest in Ash, so I just want the simplest setup possible for Ecto schemas, which is what I actually use.

I aggree, but the disadvantage is that you have to do it all over again if you edit your schema. Again, that is a tradeoff and I certainly understand your position.

Writing a mix task to do what you want is actually not too hard. You could use the debug output from my AutoLiveResource module and replace some parts with the appropriate variables in an EEx template.

The code is neatly encapsulated in a single module, which means I can publish such package myself completely independently of Backpex. The only question is whether I should do it in a different top-level namespace (e.g. BackpeXtra) or whether it would be safe to do it under something like Backpex.Extra. I guess the first option is safer, and additionally, the second option could be seen as anedorsement by Backpex, which is not the intended idea.

1 Like

I have thought about it a bit more and I’ll publish my own package under the BackpexAuto so that I can have a BackpexAuto.EctoLiveResource module (as you say, my approach is specific to the Ecto adapter).

In order to make it closer to what @Flo0807 envisioned, I have changed my package’s functionality slightly to use my new CodeGen library, which is actually great for cases such as these, where you want automatic code generation, butr in which you want to minimize the actual amount of code in your project.

First, build the common LiveResource module for you application which encapsulates database and layout information (not that if you want two different layouts you can just define two of these modules and use them in the appropriate places):

defmodule MyAppWeb.LiveResource do
  use BackpexAuto.EctoLiveResource,
    repo: MyApp.Repo,
    layout: {MyAppWeb.Layouts, :admin},
    pubsub: MyApp.PubSub
end

This has now created a β€œmeta-module” which you will use to create the live resource modules, BUT not, instead of using, you’ll be using CodeGen from my CodeGen library:

defmodule MyAppWeb.MyContext.CountryLive do
  use CodeGen,
    module: MyAppWeb.LiveResource,
    options: [
      resource: MyApp.MyContext.Patient
    ]
end

The above is very similar to calling use MyAppWeb.LiveResource, ..., except a bit more verbose. However, it has the advantage that the generated AST is divided into blocks, which you can inspect in IEx and dump the source code of some of the blocks into your actual module.

iex(2)> CodeGen.block_names(MyAppWeb.MyContext.CountryLive)
["auto_live_resource:changesets", "auto_live_resource:names",
 "auto_live_resource:fields"]

iex(5)> CodeGen.show_block(MyAppWeb.MyContext.CountryLive, "auto_live_resource:fields") 
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Block: auto_live_resource:fields
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ @impl Backpex.LiveResource
β”‚ def fields do
β”‚   [
β”‚     name: %{label: "Name", module: Backpex.Fields.Text},
β”‚     inserted_at: %{
β”‚       except: [:new],
β”‚       format: "%Y-%m-%d %H:%M:%S",
β”‚       label: "Inserted at",
β”‚       module: Backpex.Fields.DateTime,
β”‚       readonly: true
β”‚     },
β”‚     updated_at: %{
β”‚       except: [:new],
β”‚       format: "%Y-%m-%d %H:%M:%S",
β”‚       label: "Updated at",
β”‚       module: Backpex.Fields.DateTime,
β”‚       readonly: true
β”‚     }
β”‚   ]
β”‚ end
└───────────────────────────────────────────────────────

iex(4)> CodeGen.dump_source(MyAppWeb.MyContext.CountryLive, "auto_live_resource:fields")   

After dumping the source, the block is added to the module:

defmodule MyAppWeb.MyContext.CountryLive do
  use CodeGen,
    module: MyAppWeb.LiveResource,
    options: [
      resource: MyApp.MyContext.Country
    ]

  @impl Backpex.LiveResource
  def fields do
    [
      name: %{label: "Name", module: Backpex.Fields.Text},
      inserted_at: %{
        except: [:new],
        format: "%Y-%m-%d %H:%M:%S",
        label: "Inserted at",
        module: Backpex.Fields.DateTime,
        readonly: true
      },
      updated_at: %{
        except: [:new],
        format: "%Y-%m-%d %H:%M:%S",
        label: "Updated at",
        module: Backpex.Fields.DateTime,
        readonly: true
      }
    ]
  end
end
3 Likes

Backpex v0.9 release

A few days ago we’ve released Backpex v0.9.

Along with the new version, we’ve also published a redesign of our landing page: https://backpex.live/

Key highlights of v0.9:

  • New Backpex.Fields.Time field (thanks to @thanos :clap:)
  • Field option validation
  • Save & continue editing" button
  • Support for default ash destroy action

We noticed that there are many field options and you can easily get confused. So the field option validation ensures that you can only define options that are actually used by the corresponding field. It also ensures that configuration errors are caught earlier, increasing developer experience.

With large forms, you may want to save your changes more than once to ensure that you do not lose them. To address this, we’ve added a β€œSave & Continue Editing” button that allows you to save the form, but not be taken to the list view, and stay in the edit view. We have not added an option to hide the button, so we welcome feedback on this to decide whether we need to add such a configuration or not.

We also now support the basic ash destroy action, so you can now delete ash resources. We are still working on the ash integration as it is still very early days.

Breaking changes from v0.9:

  • Refactored of the field_input component to be more generic
  • Renamed the item and resource action init_change/1 callback to base_schema/1 to make it easier to understand what the function is used for
  • Changed the expected return values of the item and resource action handle functions.

Be sure to read the upgrade guide linked below, as you will need to make some changes to your code to make the latest version work.

Release Notes: Release 0.9.0 Β· naymspace/backpex Β· GitHub
Upgrade Guide: Upgrading to v0.9 β€” Backpex v0.9.1

5 Likes

Just dropped by to show my appreciation. I find the documentation to be excellent. I also find the separation of concerns to be excellent leading to it being easy enough to customize. Keep it up.

4 Likes

hi, looks really great and I am starting an Ash project right now and would like to use Backpex from day zero if possible. I see your demo code but it would be nice if you could drop some hints, perhaps even docs on how to install using Ash

Backpex v0.10 release - Phoenix LiveView 1.0

We have released Backpex version 0.10 which now supports and uses Phoenix LiveView 1.0 :tada:

This release also includes some minor documentation improvements. We’ve also relaxed the version requirements to fix dependency resolution bugs.

Note that you need to use Phoenix LiveView 1.0 in your application if you want to install Backpex v0.10.

Thanks to @thomas.fortes for the LiveView 1.0 upgrade! :raised_hands:

Release Notes: Release 0.10.0 Β· naymspace/backpex Β· GitHub

7 Likes