# Menu editor

Available from v2.3.0

The Menu editor is a Pro feature

One common task you need to do is organize your sidebar resources into menus. You can easily do that using the menu editor in the initializer.

When you start with Avo, you'll get an auto-generated sidebar By default. That sidebar will contain all your resources, dashboards, and custom tools. To customize that menu, you have to add the main_menu key to your initializer.



 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 


# config/initializers/avo.rb
Avo.configure do |config|
  config.main_menu = -> {
    section "Resources", icon: "heroicons/outline/academic-cap" do
      group "Academia" do
        resource :course
        resource :course_link
      end

      group "Blog", collapsable: true, collapsed: true do
        dashboard :dashy

        resource :post
        resource :comment
      end
    end

    section I18n.t('avo.other'), icon: "heroicons/outline/finger-print", collapsable: true, collapsed: true do
      link 'Avo HQ', path: 'https://avohq.io', target: :_blank
      link 'Jumpstart Rails', path: 'https://jumpstartrails.com/', target: :_blank
    end
  }
end
Avo main menu

For now, Avo supports editing only two menus, main_menu and profile_menu. However, that might change in the future by allowing you to write custom menus for other parts of your app.

# config/initializers/avo.rb
Avo.configure do |config|
  config.main_menu = -> {
    section I18n.t("avo.dashboards"), icon: "dashboards" do
      dashboard :dashy, visible: -> { true }
      dashboard :sales, visible: -> { true }

      group "All dashboards", visible: false do
        all_dashboards
      end
    end

    section "Resources", icon: "heroicons/outline/academic-cap" do
      group "Academia" do
        resource :course
        resource :course_link
      end

      group "Blog" do
        resource :posts
        resource :comments
      end

      group "Other" do
        resource :fish
      end
    end

    section "Tools", icon: "heroicons/outline/finger-print" do
      all_tools
    end

    group do
      link "Avo", path: "https://avohq.io"
      link "Google", path: "https://google.com", target: :_blank
    end
  }
  config.profile_menu = -> {
    link "Profile", path: "/profile", icon: "user-circle"
  }
end

A few menu item types are supported link, section, group, resource, and dashboard. There are a few helpers too, like all_resources, all_dashboards, and all_tools.

Link is the menu item that the user will probably interact with the most. It will generate a link on your menu. You can specify the name, path , and target.

link "Google", path: "https://google.com", target: :_blank
Avo menu editor

When you add the target: :_blank option, a tiny external link icon will be displayed.

# Resource

To make it a bit easier, you can use resource to quickly generate a link to one of your resources. For example, you can pass a short symbol name :user or the full name UserResource.

resource :posts
resource "CommentsResource"
Avo menu editor

You can also change the label for the resource items to something else.

resource :posts, label: "News posts"

# Dashboard

Similar to resource, this is a helper to make it easier to reference a dashboard. You pass in the id or the name of the dashboard.

dashboard :dashy
dashboard "Sales"
Avo menu editor

You can also change the label for the dashboard items to something else.

dashboard :dashy, label: "Dashy Dashboard"

# Section

Sections are the big categories in which you can group your menu items. They take name and icon options.

section "Resources", icon: "heroicons/outline/academic-cap" do
  resource :course
  resource :course_link
end
Avo menu editor

# Group

Groups are smaller categories where you can bring together your items.

group "Blog" do
  resource :posts
  resource :categories
  resource :comments
end
Avo menu editor

# Item visibility

The visible option is avaialble on all menu item. It can be a boolean or a block that has access to a few things:

  • the current_user. Given that you set a way for Avo to know who the current user is, that will be available in that block call
  • the context object.
  • the params object of that current request
  • the view_context (opens new window) object. The view_context object lets you use the route helpers. eg: view_context.main_app.posts_path.
# config/initializers/avo.rb
Avo.configure do |config|
  config.main_menu = -> {
    resource :user, visible: -> do
      context[:something] == :something_else
    end
  }
end

# Using authorization rules

When you switch from a generated menu to a custom one you might want to keep using the same authorization rules as before. To easily to that, use the authorize method in the visible option.

# config/initializers/avo.rb
Avo.configure do |config|
  config.main_menu = -> {
    resource :team, visible: -> do
      # authorize current_user, MODEL_THAT_NEEDS_TO_BE_AUTHORIZED, METHOD_THAT_NEEDS_TO_BE_AUTHORIZED
      authorize current_user, Team, "index?", raise_exception: false
    end
  }
end

# all_ helpers

We also added some helpers for the scenario where you want to customize part of a menu for convenience. For example, let's say you want to add some custom tools and mix and match the dashboards, but you don't want to disturb the resources. You can use all_resources to generate a list containing all of them.

section "App", icon: "heroicons/outline/beaker" do
  group "Dashboards", icon: "dashboards" do
    all_dashboards
  end

  group "Resources", icon: "resources" do
    all_resources
  end

  group "All tools", icon: "tools" do
    all_tools
  end
end
Avo menu editor

# Icons

For Sections, you can use icons to make them look better. You can use some local ones that we used throughout the app and all heroicons (opens new window) designed by Steve Schoger (opens new window). You can use the solid or outline versions. We used the outline version throughout the app.

section "Resources", icon: "heroicons/outline/academic-cap" do
  resource :course
end

section "Resources", icon: "heroicons/solid/finger-print" do
  resource :course
end

section "Resources", icon: "heroicons/outline/adjustments" do
  resource :course
end
Avo menu editor

# Collapsable sections and groups

When you have a lot of items they can take up a lot of vertical space. You can choose to make those sidebar sections collapsable by you or your users.

section "Resources", icon: "resources", collapsable: true do
  resource :course
end
Avo menu editor

That will add the arrow icon next to the section to indicate it's collapsable. When your users collapse and expand it, their choice will be stored in Local Storage and remembered in that browser.

# Default collapsed state

You can, however set a default collapsed state using the collapsed option.

section "Resources", icon: "resources", collapsable: true, collapsed: true do
  resource :course
end
Avo menu editor

You might want to allow your users to hide certain items from view.

# Authorization

If you use the authorization feature, you will need an easy way to authorize your items in the menu builder. For that scenario, we added the authorize helper.



 






Avo.configure do |config|
  config.main_menu = -> {
    resource :team, visible: -> {
      # authorize current_user, THE_RESOURCE_MODEL, THE_POLICY_METHOD, raise_exception: false
      authorize current_user, Team, "index?", raise_exception: false
    }
  }
end

Use it in the visible block by giving it the current_user (which is available in that block), the class of the resource, the method that you'd like to authorize for (default is index?), and tell it not to throw an exception.

Now, the item visibility will use the index? method from the TeamPolicy class.

# Profile menu

The profile menu allows you to add items to the menu displayed in the profile component. The sign-out link is automatically added for you.

You may add the icon option to the profile_menu links.

# config/initializers/avo.rb
Avo.configure do |config|
  config.profile_menu = -> {
    link "Profile", path: "/profile", icon: "user-circle"
  }
end
Avo profile menu