]> source.dussan.org Git - redmine.git/commitdiff
Introduce virtual MenuNodes (#15880).
authorJean-Philippe Lang <jp_lang@yahoo.fr>
Sat, 11 Jun 2016 06:21:52 +0000 (06:21 +0000)
committerJean-Philippe Lang <jp_lang@yahoo.fr>
Sat, 11 Jun 2016 06:21:52 +0000 (06:21 +0000)
They are characterized by having a blank url. they will only be rendered if the user is authorized to see at least one of its children. they render as links which do nothing when clicked.

Patch by Jan Schulz-Hofen.

git-svn-id: http://svn.redmine.org/redmine/trunk@15501 e93f8b46-1217-0410-a6f0-8f06a7374b81

lib/redmine/menu_manager.rb
test/unit/lib/redmine/menu_manager/menu_helper_test.rb

index fa7777065355374d614b4f7d458527f10df69f73..0d2d19a43ff27845b7ed20ba709bc43fa2bc1b28 100644 (file)
@@ -147,7 +147,15 @@ module Redmine
       end
 
       def render_single_menu_node(item, caption, url, selected)
-        link_to(h(caption), url, item.html_options(:selected => selected))
+        options = item.html_options(:selected => selected)
+
+        # virtual nodes are only there for their children to be displayed in the menu
+        # and should not do anything on click, except if otherwise defined elsewhere
+        if url.blank?
+          url = '#'
+          options.reverse_merge!(:onclick => 'return false;')
+        end
+        link_to(h(caption), url, options)
       end
 
       def render_unattached_menu_item(menu_item, project)
@@ -433,7 +441,14 @@ module Redmine
       # * Checking the permission or the url target (project only)
       # * Checking the conditions of the item
       def allowed?(user, project)
-        if user && project
+        if url.blank?
+          # this is a virtual node that is only there for its children to be diplayed in the menu
+          # it is considered an allowed node if at least one of the children is allowed
+          all_children = children
+          all_children += child_menus.call(project) if child_menus
+          return true if all_children.detect{|child| child.allowed?(user, project) }
+          return false
+        elsif user && project
           if permission
             unless user.allowed_to?(permission, project)
               return false
index 404ec64065d79c7620da4682d0564a526d50ff28..e19f066e0b6841da8e915f98ec52a2da01ca25f6 100644 (file)
@@ -208,6 +208,41 @@ class Redmine::MenuManager::MenuHelperTest < ActionView::TestCase
       end
     end
   end
+  def test_render_empty_virtual_menu_node_with_children
+
+    # only empty item with no click target
+    Redmine::MenuManager.map :menu1 do |menu|
+      menu.push(:parent_node, nil, { })
+    end
+
+    # parent with unallowed unattached child
+    Redmine::MenuManager.map :menu2 do |menu|
+      menu.push(:parent_node, nil, {:children => Proc.new {|p|
+         [Redmine::MenuManager::MenuItem.new("test_child_unallowed", {:controller => 'issues', :action => 'new'}, {})]
+       } })
+    end
+
+    # parent with unallowed standard child
+    Redmine::MenuManager.map :menu3 do |menu|
+      menu.push(:parent_node, nil, {})
+      menu.push(:test_child_unallowed, {:controller =>'issues', :action => 'new'}, {:parent => :parent_node})
+    end
+
+    # should not be displayed to anonymous
+    User.current = User.find(6)
+    assert_nil render_menu(:menu1, Project.find(1))
+    assert_nil render_menu(:menu2, Project.find(1))
+    assert_nil render_menu(:menu3, Project.find(1))
+
+    # should be displayed to an admin
+    User.current = User.find(1)
+    @output_buffer = render_menu(:menu2, Project.find(1))
+    assert_select("ul li a.parent-node", "Parent node")
+    @output_buffer = render_menu(:menu3, Project.find(1))
+    assert_select("ul li a.parent-node", "Parent node")
+
+  end
 
   def test_render_menu_node_with_children_without_an_array
     parent_node = Redmine::MenuManager::MenuItem.new(:parent_node,