diff --git a/app/controllers/application.rb b/app/controllers/application.rb index 25cf205f4..66cec7d2a 100644 --- a/app/controllers/application.rb +++ b/app/controllers/application.rb @@ -19,6 +19,9 @@ class ApplicationController < ActionController::Base before_filter :user_setup, :check_if_login_required, :set_localization filter_parameter_logging :password + include Redmine::MenuManager::MenuController + helper Redmine::MenuManager::MenuHelper + REDMINE_SUPPORTED_SCM.each do |scm| require_dependency "repository/#{scm.underscore}" end diff --git a/app/controllers/issue_categories_controller.rb b/app/controllers/issue_categories_controller.rb index 2c1c6657b..a73935b4f 100644 --- a/app/controllers/issue_categories_controller.rb +++ b/app/controllers/issue_categories_controller.rb @@ -17,6 +17,7 @@ class IssueCategoriesController < ApplicationController layout 'base' + menu_item :settings before_filter :find_project, :authorize verify :method => :post, :only => :destroy diff --git a/app/controllers/messages_controller.rb b/app/controllers/messages_controller.rb index 8078abf71..49f4ba77c 100644 --- a/app/controllers/messages_controller.rb +++ b/app/controllers/messages_controller.rb @@ -17,6 +17,7 @@ class MessagesController < ApplicationController layout 'base' + menu_item :boards before_filter :find_board, :only => :new before_filter :find_message, :except => :new before_filter :authorize diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 6add8585b..f38ca828e 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -17,6 +17,13 @@ class ProjectsController < ApplicationController layout 'base' + menu_item :overview + menu_item :activity, :only => :activity + menu_item :roadmap, :only => :roadmap + menu_item :files, :only => [:list_files, :add_file] + menu_item :settings, :only => :settings + menu_item :issues, :only => [:add_issue, :bulk_edit_issues, :changelog, :move_issues] + before_filter :find_project, :except => [ :index, :list, :add ] before_filter :authorize, :except => [ :index, :list, :add, :archive, :unarchive, :destroy ] before_filter :require_admin, :only => [ :add, :archive, :unarchive, :destroy ] diff --git a/app/controllers/queries_controller.rb b/app/controllers/queries_controller.rb index 69bad345a..0a762eee0 100644 --- a/app/controllers/queries_controller.rb +++ b/app/controllers/queries_controller.rb @@ -17,6 +17,7 @@ class QueriesController < ApplicationController layout 'base' + menu_item :issues before_filter :find_project, :authorize def index diff --git a/app/controllers/reports_controller.rb b/app/controllers/reports_controller.rb index e33fe8412..338059a50 100644 --- a/app/controllers/reports_controller.rb +++ b/app/controllers/reports_controller.rb @@ -17,6 +17,7 @@ class ReportsController < ApplicationController layout 'base' + menu_item :issues before_filter :find_project, :authorize def issue_report diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index f8b1eae81..6c2b088cc 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -24,6 +24,7 @@ end class RepositoriesController < ApplicationController layout 'base' + menu_item :repository before_filter :find_repository, :except => :edit before_filter :find_project, :only => :edit before_filter :authorize diff --git a/app/controllers/timelog_controller.rb b/app/controllers/timelog_controller.rb index f90c4527e..39e6d2fd3 100644 --- a/app/controllers/timelog_controller.rb +++ b/app/controllers/timelog_controller.rb @@ -16,7 +16,8 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. class TimelogController < ApplicationController - layout 'base' + layout 'base' + menu_item :issues before_filter :find_project, :authorize helper :sort diff --git a/app/controllers/versions_controller.rb b/app/controllers/versions_controller.rb index df1be2869..55b3a7fce 100644 --- a/app/controllers/versions_controller.rb +++ b/app/controllers/versions_controller.rb @@ -17,6 +17,7 @@ class VersionsController < ApplicationController layout 'base' + menu_item :roadmap before_filter :find_project, :authorize cache_sweeper :version_sweeper, :only => [ :edit, :destroy ] diff --git a/app/controllers/wikis_controller.rb b/app/controllers/wikis_controller.rb index a222570ef..6054abd9a 100644 --- a/app/controllers/wikis_controller.rb +++ b/app/controllers/wikis_controller.rb @@ -17,6 +17,7 @@ class WikisController < ApplicationController layout 'base' + menu_item :settings before_filter :find_project, :authorize # Create or update a project's wiki diff --git a/app/views/layouts/base.rhtml b/app/views/layouts/base.rhtml index bdaddcb3b..91c3b2634 100644 --- a/app/views/layouts/base.rhtml +++ b/app/views/layouts/base.rhtml @@ -49,13 +49,7 @@

<%= h(@project ? @project.name : Setting.app_title) %>

diff --git a/lib/redmine.rb b/lib/redmine.rb index 2dca9ed50..d0e152467 100644 --- a/lib/redmine.rb +++ b/lib/redmine.rb @@ -91,15 +91,18 @@ end # Project menu configuration Redmine::MenuManager.map :project_menu do |menu| - menu.push :label_overview, :controller => 'projects', :action => 'show' - menu.push :label_activity, :controller => 'projects', :action => 'activity' - menu.push :label_roadmap, :controller => 'projects', :action => 'roadmap' - menu.push :label_issue_plural, { :controller => 'issues', :action => 'index' }, :param => :project_id - menu.push :label_news_plural, { :controller => 'news', :action => 'index' }, :param => :project_id - menu.push :label_document_plural, { :controller => 'documents', :action => 'index' }, :param => :project_id - menu.push :label_wiki, { :controller => 'wiki', :action => 'index', :page => nil }, :if => Proc.new { |p| p.wiki && !p.wiki.new_record? } - menu.push :label_board_plural, { :controller => 'boards', :action => 'index', :id => nil }, :param => :project_id, :if => Proc.new { |p| p.boards.any? } - menu.push :label_attachment_plural, :controller => 'projects', :action => 'list_files' - menu.push :label_repository, { :controller => 'repositories', :action => 'show' }, :if => Proc.new { |p| p.repository && !p.repository.new_record? } - menu.push :label_settings, :controller => 'projects', :action => 'settings' + menu.push :overview, { :controller => 'projects', :action => 'show' }, :caption => :label_overview + menu.push :activity, { :controller => 'projects', :action => 'activity' }, :caption => :label_activity + menu.push :roadmap, { :controller => 'projects', :action => 'roadmap' }, :caption => :label_roadmap + menu.push :issues, { :controller => 'issues', :action => 'index' }, :param => :project_id, :caption => :label_issue_plural + menu.push :news, { :controller => 'news', :action => 'index' }, :param => :project_id, :caption => :label_news_plural + menu.push :documents, { :controller => 'documents', :action => 'index' }, :param => :project_id, :caption => :label_document_plural + menu.push :wiki, { :controller => 'wiki', :action => 'index', :page => nil }, + :if => Proc.new { |p| p.wiki && !p.wiki.new_record? }, :caption => :label_wiki + menu.push :boards, { :controller => 'boards', :action => 'index', :id => nil }, :param => :project_id, + :if => Proc.new { |p| p.boards.any? }, :caption => :label_board_plural + menu.push :files, { :controller => 'projects', :action => 'list_files' }, :caption => :label_attachment_plural + menu.push :repository, { :controller => 'repositories', :action => 'show' }, + :if => Proc.new { |p| p.repository && !p.repository.new_record? }, :caption => :label_repository + menu.push :settings, { :controller => 'projects', :action => 'settings' }, :caption => :label_settings end diff --git a/lib/redmine/menu_manager.rb b/lib/redmine/menu_manager.rb index d4a46b3e1..c801cb383 100644 --- a/lib/redmine/menu_manager.rb +++ b/lib/redmine/menu_manager.rb @@ -17,6 +17,63 @@ module Redmine module MenuManager + module MenuController + def self.included(base) + base.extend(ClassMethods) + end + + module ClassMethods + @@menu_items = Hash.new {|hash, key| hash[key] = {:default => key, :actions => {}}} + mattr_accessor :menu_items + + # Set the menu item name for a controller or specific actions + # Examples: + # * menu_item :tickets # => sets the menu name to :tickets for the whole controller + # * menu_item :tickets, :only => :list # => sets the menu name to :tickets for the 'list' action only + # * menu_item :tickets, :only => [:list, :show] # => sets the menu name to :tickets for 2 actions only + # + # The default menu item name for a controller is controller_name by default + # Eg. the default menu item name for ProjectsController is :projects + def menu_item(id, options = {}) + if actions = options[:only] + actions = [] << actions unless actions.is_a?(Array) + actions.each {|a| menu_items[controller_name.to_sym][:actions][a.to_sym] = id} + else + menu_items[controller_name.to_sym][:default] = id + end + end + end + + def menu_items + self.class.menu_items + end + + # Returns the menu item name according to the current action + def current_menu_item + menu_items[controller_name.to_sym][:actions][action_name.to_sym] || + menu_items[controller_name.to_sym][:default] + end + end + + module MenuHelper + # Returns the current menu item name + def current_menu_item + @controller.current_menu_item + end + + # Renders the application main menu as a ul element + def render_main_menu(project) + links = [] + Redmine::MenuManager.allowed_items(:project_menu, User.current, project).each do |item| + unless item.condition && !item.condition.call(project) + links << content_tag('li', + link_to(l(item.caption), {item.param => project}.merge(item.url), + :class => (current_menu_item == item.name ? 'selected' : nil))) + end + end if project && !project.new_record? + links.empty? ? nil : content_tag('ul', links.join("\n")) + end + end class << self def map(menu_name) @@ -48,13 +105,14 @@ module Redmine end class MenuItem - attr_reader :name, :url, :param, :condition + attr_reader :name, :url, :param, :condition, :caption def initialize(name, url, options) @name = name @url = url @condition = options[:if] @param = options[:param] || :id + @caption = options[:caption] || name.to_s.humanize end end end diff --git a/public/stylesheets/application.css b/public/stylesheets/application.css index fa76948d2..d370f1b42 100644 --- a/public/stylesheets/application.css +++ b/public/stylesheets/application.css @@ -34,7 +34,7 @@ h4, .wiki h3 {font-size: 12px;padding: 2px 10px 1px 0px;margin-bottom: 5px; bord padding: 4px 4px 4px 4px; background: #2C4056; } -#main-menu li a:hover {background:#759FCF;} +#main-menu li a:hover, #main-menu li a.selected {background:#759FCF;} #main {background: url(../images/mainbg.png) repeat-x; background-color:#EEEEEE;}