TrestleAdmin / trestle

A modern, responsive admin framework for Ruby on Rails
https://trestle.io
GNU Lesser General Public License v3.0
1.94k stars 173 forks source link

Option to disable form as "show" view? #436

Open joshmn opened 1 year ago

joshmn commented 1 year ago

Hello!

First, thank you for Trestle. It has been lovely to work with. I had a project for six years that I managed via ActiveAdmin which was also very nice to work with — meaning, yes, I was really comfortable with ActiveAdmin — but for a new project I decided to give Trestle a go and it's been great. Granted, I have patched the hell out of it to match some AA-like behavior, but even with that, 👨🏻‍🍳💋

One weird thing I have encountered is that by default, Trestle assumes you want to edit something. Sure, okay, that makes sense — edit is really close to show. But sometimes, I just want to view a resource and then have tabs to manage a related association on that same page. The most basic example I can think of this is "an admin wants to leave a comment about this resource"

My intuition said (yes, show is mine):

show do
  default_attributes do
    sidebar do
      h5 "Total: #{number_to_currency instance.total_in_cents / 100.0}"
      h5 "Balance: #{number_to_currency instance.balance_in_cents / 100.0}"
      # ... 
    end
  end
  tab :cancel, label: "Create cancelation" do
    render 'admin/comments/comments'
  end
end

Where in admin/comments/_comments.html.erb:

 <%= simple_form_for Comment.new, url: CommentsAdmin.path do |f| %>
    <%= f.input :body, label: false %>
    <%= f.input :resource_type, as: :hidden, input_html: { value: instance.class } %>
    <%= f.input :resource_id, as: :hidden, input_html: { value: instance.id } %>
    <%= f.submit %>
  <% end %>

Unfortunately this didn't work because it was getting rendered inside of the form context for the default Trestle::Form::Renderer.

So I had to:

</form> <!-- big yikes -->
 <%= simple_form_for Comment.new, url: CommentsAdmin.path do |f| %>
    <%= f.input :body, label: false %>
    <%= f.input :resource_type, as: :hidden, input_html: { value: instance.class } %>
    <%= f.input :resource_id, as: :hidden, input_html: { value: instance.id } %>
    <%= f.submit %>
  <% end %>

This was a big surprise.

I know that you're plugging away at the Stimulus/Hotwire changes; I'd be happy to connect and make some PRs for this if you'd like. I don't know what it'd look like though because it kind of fundamentally changes all of Trestle's expected behavior for the "show" view, but I'd be happy to contribute if you'd be so willing to have me.

Perhaps it'd just close out the form tag in the first tab? I don't know how many users are using tabs to separate different parts of the form — so it'd be certainly breaking. Granted, RailsFlixDemo does have this as an example (https://github.com/TrestleAdmin/RailsFlixDemo/blob/main/app/admin/movies_admin.rb) so perhaps opt-in?

This seems most natural to me:

Trestle.resource(:movies) do
  show do 
    tab instance.title do 
      form MoviesAdmin.form 
    end

    tab "Comments" do
      form CommentsAdmin.form, resource: instance 
    end

    tab "Crew" do 
      table CrewCreditsAdmin.table, collection: movie.crew_credits.includes(:person)
    end
  end

  form do 
    # ...
  end
end

Maybe check if show is a defined as a renderer inside of an admin block and if it is, change the default view and route? Oof. Again, I'd be happy to contribute if you see this as worth contributing. (Also have filters w/ Ransack and batch actions that I can send up, but certainly would need some help on the front-end — separate conversation though)

joshmn commented 1 year ago

This appears similar to #413