smpallen99 / ex_admin

ExAdmin is an auto administration package for Elixir and the Phoenix Framework
MIT License
1.2k stars 272 forks source link

Complete Refactor of ExAdmin #367

Open smpallen99 opened 7 years ago

smpallen99 commented 7 years ago

We've had issue #166 open for a long time. @dsnider and I have been working on some ideas that we think will make ExAdmin much more extensible, and fit better with the "Phoenix and Elixir" way. I have started working on prototyping of a complete overhaul of the ExAdmin architecture.

Justification

ExAdmin was developed for my first Phoenix Application. The approach I took, although functional, does not align very well with the Phoenix way. Furthermore, I feel that we can do better without the heavy use of DSLs. Finally, I've never been happy with the theme support implementation.

Design Goals

Ideas being kicked around

This will be a break point release. No backwards compatibility.

I welcome your ideas and feedback. Steve

tmbb commented 7 years ago

First I have to tell you that ExAdmin is currently GREAT, from the user's point of view, especially for apps with little data.

That said, I'm a little new to this whole web app stuff, but I'd like to propose some ideas. I hope the feedback of a beginner like me might be useful too.

Design Goals

break the package apart into a series of composable components: does this mean users would be able to reuse the UI for general CRUD forms? If so, it might be useful, otherwise breaking it apart just for the sake of it might degrade the user experience (you'd know this, of course).

easy to update with extensive customization: This would be good, especially in things like customizing the name of the relation in drop-down choices.

intelligent defaults: the defaults are already pretty intelligent. Which defaults do you consider "less intelligent"?

optimize the architecture to support large data (no association drop-downs with thousands of entries): I agree that drop-down menus might be inconvenient for thousands of entries, but I'd like to keep being able to have some way to display and update such associations. For some cases a select2 widget that loads data through Ajax might be a good choice, while for others a full customizable search form (with proper paging) might be better.

Ideas being kicked around

JS data tables: please take a look into VueJS. It's a JS framework which is very simple to use with an .eex-like template engine that's really intuitive to use and can be generated server-side as if it were normal HTML. It supports 2-way data-binding in a way that's very clear and simple to understand. You have great widgets out of the box, and it's very easy to develop new ones. You can learn most of it in a day, and become quite good over a weekend, I think.

Revamped sidebar filter: real time updates: VueJS + Phoenix channels is pure love for live UI updates.

Remove the html DSL and replace it with Slim templates: This would probably be good, as you replace a ad hoc (and probably incomplete) implementation of HTML templates with a battle tested general template engine, with good documentation. I haven't looked at the your code as it is now, and it's quite possible it's better than Slim, I'm just saying that adopting Slim sounds like the right choice.

buffer the dependency on Ecto: does this mean ExAdmin will adopt Phonix's contexts in 1.3? This would probably be a good thing, but I'm a little afraid that Phoenix 1.4 might decide that contexts are anot as good after all and there is a much better abstraction (TM) we should all be using and that would render ExAdmin useless. At least with Ecto schemas you know that changes in Phoenix's project organization won't pull the rug from under your feet.

Extra

Internationalization - while this is a backend tool, internationalization might be important for use cases in which the admins don't speak English. We could use the approach we used in Coherence (and replace the bare gettextcalls with dgettext "ex_admin"). I can help.

smpallen99 commented 7 years ago

@tmbb Thanks for the feedback!! Funny, I did not look at who posted this great feedback until the end of reading it :). Then I noticed it was you...

Some of my projects use ExAdmin as the only UI, not just a backend solution. So, yes, the intent is to make it a good solution for developing a front facing solution. That is part of the reason to break it into components. Additionally, the goal is to allow users to bring only parts into their solution, without the need for the whole solution.

Yes, we will adopt all your excellent contributions to Internationalization from Coherence 👍 and your help would be greatly appreciated. But first, I need to sketch out the new architecture.

Yes, Vue.js has been brought to my attention as well as other options. I'm also very familiar with channels and the options available to use them. See the architectural notes on ucx_ucc for some of the stuff I'm doing with that project.

As for the idea of buffering the dependency of on Ecto, I'm thinking that it will be independent of the opinions of Phoenix. Phoenix contexts are mainly a concern of the generators. A designer can implement their own architecture. So, we cannot assume any particular structure. I guess we need two things, the module for the schema (to reflect) and the module for the changeset. They may be different modules, or the same module. Personally, I like to keep the changesets with the schema, but I have some projects with the split.

I'm already pretty happy with the defaults of ExAdmin. I listed that item to indicate the we will be keeping the same strategy.

In closing, I'm a pretty heavy user of ExAdmin myself. So, I have a pretty good idea of its strengths and weaknesses. I also understand that may users of ExAdmin are pretty new to Phoenix and Elixir. So my goal is to provide a model that supports both the beginner and the advances. Of course, feedback from the community will keep me in check if I stay during the project.

Again, thanks a lot for your excellent feedback.

smpallen99 commented 7 years ago

Here are some ideas I've been playing around with the the new architecture:

I would like to reduce the amount of config required for ExAdmin. I have a small demo app created. Here is an example of the ExAdmin configuration so far. Config Example

The following User Resource File shows how index page customization can be done.

The following Theme Index Template shows how I might handle theme generation and customization. This is a significant departure from the current DSL approach. I'm provided a generator eex template. It compile the embedded slim template for each of the controller actions.

I personally like this approach since it used standard Phoenix approaches to building your admin site. This differs from standard generators since you can make changes to this index template and all index pages will be compiled based on this file. I'll have individual index templates like this for each resource so you can customize individual resource action pages.

I have also created a schema adapter and a reference implementation for Ecto. This will allow you to create adapters for non-ecto models. You will be able to specify a global adapter in the config and override it for any individual resource. This will give you the flexibility to mix and match resources in different formats. See the Ecto Schema Adapter Example.

I'd love to hear what people think of this approach so far.

Ch4s3 commented 7 years ago

I kind of get the inclination to use Slim, as I used to be a Haml fan, but I think eex works well enough and doesn't add an extra dependency. Its also close enough to HTML that contributors can dive in and get it more easily.

smpallen99 commented 7 years ago

@Ch4s3 Thanks for the feedback!! I have been considering supporting both slim and eex which could be specified when running the generators. Or, perhaps an addon package to support the other . I guess, the standard default is eex... Lets hear what others have to say 👍

tmbb commented 7 years ago

@smpallen99 Supporting both seems like too much work for little benefit. But if the implementation is very easy, I guess it's a possibility.

tmbb commented 7 years ago

Slim is much more concise than eex, and I like it. Using eex templates to generate slim templates has the advantage that it makes it easy to deal with escaping. So your idea of having eex templates generate slim templates makes sense. As @Ch4s3 said above, the use of a new template language must be weighted against the cognitive load it brings into the mix.

PS: eex has the "aesthetic" benefit of looking less magic, and much closer to HTML, while Slim looks like black magic for people unfamiliar with HTML (even though it's simple and well defined). This is extremely superficial, though, and I don't know how much thought should be given to this argument Personally I lean towards Slim, but I'm aware of the disadvantages I mentioned above.

tmbb commented 7 years ago

Regarding user.ex, what does this line do?

smpallen99 commented 7 years ago

@tmbb I added more to the gist with an explanation TL;DR adds :id field and removes [:active, :birthdate, :height] fields from the default reflected fields on the resource.

tmbb commented 7 years ago

Ok, thanks!

Ch4s3 commented 7 years ago

@smpallen99 Yeah, supporting both with an option on the generator sounds very nice.

smpallen99 commented 7 years ago

I’m thinking that this could be an add-on package. This will make a nice small project for someone to contribute :) I’ll be doing the development in slim. We can decide later if the default should be slime or eex.

Another thought, It will be easier to read and work with slim since you won’t have to deal with all the EEx escaping, IMHO.

TL;DR I’m listening to the feedback… I want to do the original dev in Slim, but we’ll find a way to meet the community’s needs…Thanks!!

On May 16, 2017, at 10:05 AM, Chase Gilliam notifications@github.com wrote:

@smpallen99 https://github.com/smpallen99 Yeah, supporting both with an option on the generator sounds very nice.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/smpallen99/ex_admin/issues/367#issuecomment-301793110, or mute the thread https://github.com/notifications/unsubscribe-auth/AA2YpXYfLcTU354abiaKI7JmLKcmlSQtks5r6a1AgaJpZM4NZ9pi.

smpallen99 commented 7 years ago

I want to acknowledge @dsnider for his excellent ideas and motivation to get me started on this redesign. Many of the ideas that I'm prototyping here are from Dan. This would still be something that want to do in the future if it was not for him!

astery commented 7 years ago

Maybe it's a rare issue, and make things more complicated.

I don't see how to have multiple admin endpoints (UIs) in one web app. It can be helpful when you rebuild admin and want to have old one usable, or you want to have different UIs for different roles.

For now, you can create separate admin app and setup it on a different port, and configure nginx after.

But I think about something like this (like ecto does):

config :my_app, MyApp.Web.SuperAdmin,
  resources: [
    MyApp.ExAdmin.Country,
    MyApp.ExAdmin.State,
    MyApp.ExAdmin.User,
  ], 
  theme: "material_bootstrap", 

config :my_app, MyApp.Web.ManagerAdmin,
  resources: [
    MyApp.ExAdmin.Products,
  ], 
  theme: "manager_material_bootstrap", 

defmodule MyApp.Web.SuperAdmin do
  use ExAdmin, otp_app: :my_app
end

defmodule MyApp.Web.ManagerAdmin do
  use ExAdmin, otp_app: :my_app
end

defmodule MyProject.Router do
  use MyProject.Web, :router
  require MyApp.Web.SuperAdmin
  require MyApp.Web.ManagerAdmin

  scope "/admin", MyApp.Web.SuperAdmin do
    pipe_through :browser
    MyApp.Web.SuperAdmin.routes()
  end

  scope "/manager", MyApp.Web.ManagerAdmin do
    pipe_through :browser
    MyApp.Web.ManagerAdmin.routes()
  end
end

Maybe it's achievable in more simplier way, just a proposal for new design.

smpallen99 commented 7 years ago

@astery precisely what I was working on last night. Good catch!!

astery commented 7 years ago

@smpallen99 awesome to hear it :+1:

chrisjowen commented 7 years ago

Im new to ExAdmin (as in looked at it yesterday), I think its a great and obviously a lot of good work went into it.

I'm also relatively new to elixir and have been looking to help out on a fun an interesting OSS project. If you are looking to do a complete rewrite I'd like to offer to help out with documentation, and some minor issues until I have a decent grasp of the project.

What I have found its that it's quite difficult without some serious code diving to figure out whats possible, and whats still WIP with the library. It's a bit daunting that there are so many live branches, PRs and issues I think it might be worth getting those stripped down a bit before starting a rewrite, I'm happy to help here too where I can.

I really like direction your going with the Ecto schema adaptor and Resource, I'm less interested which direction you choose for templating just as long as its flexible and it looks like it will be.

Currently, the has_many part of the resource DSL feels a little bit like a bolt on and has some unexpected behaviours. But it feels like a really nice and important feature to have a way of adding/editing/removing associations in the same form. So I'd be really interested in getting this, or similar to be a first class concern in the rewrite.

smpallen99 commented 7 years ago

Hey everyone.

If you are interesting in seeing/trying what we have on the new architecture, you can find it under the new ex-admin group. You can try it out with the example project.

Couple notes about the new architecture:

Let me know if your interested in contributing. There's lots of work to be done before this is ready for general use. At this point, it's not ready to use. However, the demo project should be functional.

Also note that we will be renaming the group and the package once a new name has been chosen. I'm open to suggestions 👍

@chrisjowen Thanks for you input. I have only looked at simple belongs_to associations at this point. Will be looking at many_to_many soon.

tmbb commented 7 years ago

@smpallen99 Are you asking for suggestions for a new package name for the new version of ExAdmin?

smpallen99 commented 7 years ago

@tmbb I'm open to suggestions. Keep in mind that we would like to change the focus of the new architecture to more of a general site builder than just an admin builder.

smpallen99 commented 7 years ago

Quick update... I'm making good progress on the the version. We finally picked a name. The new ExAdmin is called talon. You can find it at https://github.com/talonframework/talon. Aside from the new architecture, the index page now supports a live search feature that searches all text fields shown on the page.

Creating new themes are pretty simple. I have a new generator for creating a new theme.

The project is not ready yet for use. I have more work to do on field type rendering, associations, and the generators.

Issues in the backlog have all been tagged, and a few milestones defined.

The Talon Demo project is available if anyone wants to check out the new version.