Mandarin + Forage - An admin tool for phoenix

You can follow the instructions here: https://github.com/tmbb/bureaucrat_demo_app

Just replace the depndencies by their hex package names and versions, and replace all occurrencies of bureaucrat by mandarin in the commands.

This will generate the correct files right where you need them. The hardest part is to learn how to use the forage package, but you ca learn a lot by looking at the generated .ex and .eex files.

Thanks, I’ll try that tomorrow! My next question is: do you have any roadmap or commitments for the project? I’m looking for a solution that I can put on production.

1 Like

I’m not thinking about changing a lot of things in the Mandarin generators. I’ll add some features to the routing macros to make them more customizable. But that’s probably it.

Regarding forage, I’m very happy with the current API. But I need to add tests.

I still need to add support for many to many relationships somehow, between Forage and Mandarin.

But mainly my goal is to make things stable and well tested so that ir can be used in production. Mandarin is very safe to use, because it’s mostly generators which generate “normal” phoenix files. Forage is another question, because it’s the project that actually runs some code at runtime…

By the way, did you find Mandarin simple to use?

Somewhat. Couple of points:

  1. It would be great to add an extended description of what this package really does and what’s the use case. I’m a bit confused. My use case is that I have an existing DB and I’m putting a read-only RESTful API on top of that (with a little help from phx.gen), but I would also like to have an admin interface for modifying the data. Can mandarin help me? I find myself doing hacks so that the generators do not overwrite my schemas and controllers. I might go with creating a separate schemas for mandarin but this requires manual work.
  2. I’m not fully convinced about the idea of using generators. If I need any customization, then I can’t re-generate the admin panel. What if mandarin gets a major bump and I’d like to update my admin panel? Seems that I would have to start from scratch.
  3. If I understand this right, mandarin “just” provides better generators then the default Phoenix ones, right? If so, why do I have to include it in prod build? Or maybe that’s not the case?
  4. There are some places that require renaming from the old name: for example here and here.
  5. There seems to be a bug when a schema references another one and the id can be null. Not sure if all the relationship are preloaded, but in this line I get an error: nil.id/0 is undefined.
  6. The templates assume that the timestamps are present in the schemas. My schemas actually use timestamps(inserted_at: :created_at).
  7. I’ve tried torch as well - the advantage of mandarin is that it works with Ecto 3.x.
  8. I wanted to give ExAdmin a try, but it’s not actively maintained and the deps are pinned to pretty old versions.

In the end, I think I would find it more useful to have a library of generic views/templates/helpers so that I can throw any struct at it and render it (possibly exclude some fields) or build something in just a few lines of code.

2 Likes

I think it’s clear that Mandarin is not for your use case then. What you describe (and what ExAdmin does) is very hard to customize, and that’s why I’ve chosen the current architecture.

You have to include it because of the Router macros and the mandarin respuce plug, which must be present at least when the app is compiled.

Back to Mandarin after a long time away… What is the recomended approach to testing a package that mostly dumps text int your Phoenix apps? I don’t think unit tests or integration tests are easy to write for this… Do people just use manual testing? Anyone has any tips?

1 Like

Example application built using mandarin (and forage, of course): https://github.com/tmbb/mandarin_office (the README explains how to generate the project).

I need to document forage better and expand on the readme to explain what the generated files do. It’s true that the generator dump a lot of code into your files, but doing that instead of using clever macros makes everything much more extendable (even if a little harder to understand due to the raw volume of code you have to read).

Thank you very much to share this app. I would like to use it but when I run mix ecto.reset, I have the following error:

10:05:25.545 [info]  create table employees
** (Postgrex.Error) ERROR 42804 (datatype_mismatch) foreign key constraint "employees_department_id_fkey" cannot be implemented

Key columns "department_id" and "id" are of incompatible types: uuid and bigint.

For 10. on your Readme, I used

mix mandarin.gen.html Admin Function functions name:string --binary-id

since 10 is the same than 8

Add a  `Function`  resource:  `mix mandarin.gen.html Admin Department departments name:string`

To make it work, I had to delete the file bureaucrat.ex in deps/mandarin/mix/ (I also deleted the folder bureaucrat) because I had the following error:

== Compilation error in file lib/mix/mandarin.ex ==

** (CompileError) lib/mix/mandarin.ex:1: cannot define module Mix.Mandarin because it is currently being defined in lib/mix/bureaucrat.ex:1

(stdlib) erl_eval.erl:680: :erl_eval.do_apply/6

**could not compile dependency :mandarin, "mix compile" failed. You can recompile this dependency with "mix deps.compile mandarin", update it with "mix deps.update mandarin" or clean it with "mix deps.clean mandarin"**

I think it’a because you haven’t created the Department resource with —binary-id. That’s my mistake, of course.

Thank you very much. It’s now working. I really like the Admin interface.
You should update the readme to add —binary-id for 8.

Of course, my mistake

The README at https://github.com/tmbb/mandarin_office has been updated with the correct instructions.

1 Like

Thanks for the quick update. It would be good also to update #10

Add a Function  resource:  mix mandarin.gen.html Admin Function functions name:string --binary-id

instead of

Add a  Function  resource:  mix mandarin.gen.html Admin Department departments name:string

Fixed it.

Hey, when do you estimate that this project will be production ready?

I think there is a bigger demand than we think when it comes to admin generators, especially a standardized one that becomes a default recommendation. This would be positive in many ways, as in several contributors, more knowledge spread around and of course a great product.

I wish I could contribute but I don’t think I have the elixir experience yet to be useful, but I will fork and test the repo when I get home from work and try it out for feedback purposes :slight_smile:

I don’t really have an estimate for when I have the docs done. Mandarin is mostly ready for production use now. You can create an admin backend using the generators and pretty much never touch the code (except to add authentication and authorization to the pipeline and things will work. The problem is that appart from the “tutorial” in the example repo there are no docs.

But even worse is the fact that Forage doesn’t have 100% code coverage yet, and docs are also pretty sparse. There’s also the problem that Forage web doesn’t yet support disjunction (the OR operator) in queries yet, but that’s not very important in my opinion.

Hm… I don’t know if thde demand for admin generators is that big. I think people would prefer an admin framework that worked based on DSLs and macros. Mandarin has been criticised for generating a lot of code, when much of it could be simplified with. The controller could be something like this:

defmodule App.Admin.Employee do
  use Mandarin.Controller, resource: App.Admin.Employee
  # with defoverridable functions, of course
end

It’s actually much more work to generate a file with the controller code. I’m doing it because I believe it’s easier to customize if all code is explicit (and you’ll want to customize it sooner or later…).

1 Like

Just trying to get some feedback :slight_smile: Has anyone actually tried this admin interface in a user-facing app, even if for an internal app? I’ve been quiet for a long time but I’m thinking on going back to it (I have a project that might use this)

Nope, not yet, never got around it. Was wondering between this one and a few others but I am more open to try some of what they call them today “low-code” or “no-code” internal app builders (of which there’s a lot).

Hm… what is a good example of a “low code” app builder? I’m not very familiar with those.

Here are a few lists:

EDIT: And a HN thread where a number of such tools are shown as well:

Ask HN: Best low-/no-code solution for simple web-based database frontends