Adrian any plans to break out the menu
# avo-2
a
Adrian, any plans to break out the menu generation code and let it be used in other areas of the app? I need some contextual menus, and I'd love to just use the current menu builder stuff with it.
l
we don't have that planned yest, but I can sse it as a separate feature
where in the panel you'd like to show it. can you send a screenshot or an example?
a
sure

https://cdn.discordapp.com/attachments/1123647534468960367/1123656160361336962/image.png

In this case, that's a resource tool, with a sidebar in the PanelComponent, and the beginnings of a menu in the sidebar component.
I have to hook the stimulus stuff up so it doesn't actually collapse, etc, now
l
that looks pretty good!
Good job!
a
I'm basically imitating what you did in sidebar_component.html.erb
l
haha. if it works, it works!
a
but I'd really like to be able to use the same sort of syntax that you do for the main menu
I feel it's nice and clean that way, vs having lots of logic in the view
If you don't have it on your radar, I'll keep at it and if it's a clean implementation I'll send a PR for it
l
yeah. we can't commit to it right now, but I can see having something like this
Copy code
ruby
class WorkflowEditorMenu < Avo::BaseMenu
  def items
    link_to ...
    resource...
  end
end
render WorkflowEditorMenu.new
somewhere in the code...
a
right now I have a concern vs a subclass
that I'm including the same way that you suggest for modifying ApplicationController
but a subclass may be a better way to go
l
we don't have that yet, but that's how I see the API being
a
I'll also need to have a way to add/extend the relevant components
like adding a WorkflowComponent to the ItemSwitcher stuff
l
yeah. I agree!
we need to think of a good way to do it
a
I'll play around a bit, see what I can come up with
do you have a place already that I can put app-specific components?
l
what is app-specific? can you share an example?
a
well, like you have Avo::Sidebar::LinkComponent What if I wanted to have a MenuItem::WorkflowComponent for use in the menu
or even Avo::Sidebar::WorkflowComponent
l
I'd use the regular
app/components
dir and follow the conventions
app/components/avo/sidebar/workflow_component.rb
a
ok, that's what I figured
makes sense to me to keep it in the same module as the rest of the menu
l
yeah. you just have to watch out for conflicts (Avo namespace)
yeah. conventions rule. it's not worth it to break out for this scenario IMHO
a
@lemon-wall-20836 if I'm wanting to add new menu components (e.g. Avo::Menu::WorkflowAction and the corresponding Avo::Sidebar::WorkflowActionComponent) in my app, where should I put it to keep within Avo conventions? (Since I'll develop this as a PR eventually, I want to make sure it's in the right spot for Avo)
(for now I put WorkflowAction in app/lib/avo/menu and the component files in components/avo/sidebar )
so I guess the real question is just where to put the Menu item
l
that's correct
a
perfect
alright @lemon-wall-20836 ... been monkeying around with this for a while. Looks like the hard part is going to be adding new menu component types that are app specific to components/avo/sidebar/item_switcher_component.html.erb Have you given any thought at all about how this might be made a little more generic? I have the whole system running with arbitrary menus, but adding app specific components breaks things.
Need a way to either append to that view with custom entries like this: or maybe move that logic to the component ruby file in the #call method.
Would also love to understand why the component type specific stuff (like label, path, target, data, icon in the above example) is in the view there, vs having it in the Avo::Menu::Link class. Feels like LinkComponent should know how to render an Avo::Menu::Link w/o getting anything from the ComponentSwitch helper class
l
yeah. I forsaw this issue, and I have an idea on how we could approach it
instead of the
ItemSwitcher
(which I created because I was lazy), we add a
def component
method on the
Avo::Menu::BaseItem
which will produce the name of the view component used by the renderer.
Copy code
ruby
#pseudo code
class Avo::Menu::BaseItem
  def namespace
    # code that transforms classes from Avo::Menu::Link to Link
  end

  def view_component
    "Avo::Sidebar::#{name_without_namespace}Component".safe_constantize.new **view_component_args
  end

  def view_component_args
    {
      label: item.label,
      path: item.path,
      ...
    }
  end
end
so instead we generate the items like so
Copy code
erb
<!-- Instead of this -->
          <% Avo::App.main_menu.items.each do |item| %>
            <%= render Avo::Sidebar::ItemSwitcherComponent.new item: item %>
          <% end %>

<!-- Something like this of this -->

          <% Avo::App.main_menu.items.each do |item| %>
            <%= render item.view_component %>
          <% end %>
so we can now create new item types for the menu with the item file (ex:
Avo::Menu::Link
) and view component files (ex:
Avo::Sidebar::LinkComponent
) and they can self-register
what do you think about this approach?
I think that with this approach we could extract the whole functionality in an external gem for everyone to use
a
yes, that's very much like what I was thinking too.
I have it all working locally in an 'override' fashion right now, so I will take a crack at adapting my local stuff to work this way, and once it's working I'll let you know
l
sounds good
looking forward to seeing what you got