diff --git a/app/controllers/my_controller.rb b/app/controllers/my_controller.rb index 8ef263e..5e58076 100644 --- a/app/controllers/my_controller.rb +++ b/app/controllers/my_controller.rb @@ -22,6 +22,7 @@ class MyController < ApplicationController helper :issues helper :users + helper :queries helper :custom_fields BLOCKS = { 'issuesassignedtome' => :label_assigned_to_me_issues, @@ -45,6 +46,7 @@ class MyController < ApplicationController # Show user's page def page @user = User.current + @all_blocks = Redmine::Views::MyPage::Block.all_blocks @blocks = @user.pref[:my_page_layout] || DEFAULT_LAYOUT end @@ -139,13 +141,33 @@ class MyController < ApplicationController # User's page layout configuration def page_layout @user = User.current + @all_blocks = Redmine::Views::MyPage::Block.all_blocks @blocks = @user.pref[:my_page_layout] || DEFAULT_LAYOUT.dup + blocks_in_use = @blocks.values.flatten + + # users may lose access to issue queries, it doesnt hurt to clean up their + # layout from time to time: + if (inaccessible_blocks = blocks_in_use - @all_blocks.keys).any? + %w(top left right).each do |f| + @blocks[f] -= inaccessible_blocks if @blocks[f] + end + @user.pref[:my_page_layout] = @blocks + @user.pref.save + end + @block_options = [] BLOCKS.each do |k, v| - unless @blocks.values.flatten.include?(k) + unless blocks_in_use.include?(k) @block_options << [l("my.blocks.#{v}", :default => [v, v.to_s.humanize]), k.dasherize] end end + + @issue_query_block_options = [] + Redmine::Views::MyPage::Block.issue_query_blocks.each do |id, name| + unless blocks_in_use.include?(id) + @issue_query_block_options << [name, id] + end + end end # Add a block to user's page @@ -153,7 +175,7 @@ class MyController < ApplicationController # params[:block] : id of the block to add def add_block block = params[:block].to_s.underscore - if block.present? && BLOCKS.key?(block) + if block.present? && Redmine::Views::MyPage::Block.all_blocks.key?(block) @user = User.current layout = @user.pref[:my_page_layout] || {} # remove if already present in a group diff --git a/app/helpers/my_helper.rb b/app/helpers/my_helper.rb index fdb51d6..c8b5154 100644 --- a/app/helpers/my_helper.rb +++ b/app/helpers/my_helper.rb @@ -31,6 +31,24 @@ module MyHelper Document.visible.order("#{Document.table_name}.created_on DESC").limit(10).to_a end + def mypage_available_block_options + options = options_for_select(@block_options) + options += grouped_options_for_select([[l(:label_query_plural), @issue_query_block_options]]) if @issue_query_block_options.any? + return options + end + + def render_mypage_box(block, user = @user) + locals = { user: user } + partial = case block.to_s + when /^issue_query_(\w+)$/ + locals[:query] = IssueQuery.visible.find $1 + "my/blocks/issue_query" + else + "my/blocks/#{block}" + end + render partial: partial, locals: locals + end + def issuesassignedtome_items Issue.visible.open. where(:assigned_to_id => ([User.current.id] + User.current.group_ids)). diff --git a/app/views/my/_block.html.erb b/app/views/my/_block.html.erb index 813eb2b..fd79680 100644 --- a/app/views/my/_block.html.erb +++ b/app/views/my/_block.html.erb @@ -5,6 +5,6 @@
- <%= render :partial => "my/blocks/#{block_name}", :locals => { :user => user } %> + <%= render_mypage_box block_name, user %>
diff --git a/app/views/my/blocks/_issue_query.html.erb b/app/views/my/blocks/_issue_query.html.erb new file mode 100644 index 0000000..de07509 --- /dev/null +++ b/app/views/my/blocks/_issue_query.html.erb @@ -0,0 +1,56 @@ +

+ <%= link_to query.name, query.project ? project_issues_path(query.project, query_id: query.id) : issues_path(query_id: query.id) %> + (<%= link_to_project(query.project) + ', ' if query.project %><%= query.issue_count %>) +

+ +<% @issue_count_by_group = query.issue_count_by_group %> + +<% if query.issue_count > 0 %> + <%= form_tag({}) do %> + + + <% query.inline_columns.each do |column| %> + + <% end %> + + <% previous_group = false %> + + <% issue_list(query.issues(limit: 10)) do |issue, level| -%> + + <% if query.grouped? && (group = query.group_by_column.value(issue)) != previous_group %> + <% reset_cycle %> + + + + <% previous_group = group %> + <% end %> + + "> + + <%= raw query.inline_columns.reject{|c| c.name == :id}.map {|column| ""}.join %> + + + <% end %> + +
<%= column.caption %>
+   + <%= group.blank? ? l(:label_none) : column_content(query.group_by_column, issue) %> <%= @issue_count_by_group[group] %> + <%= link_to_function("#{l(:button_collapse_all)}/#{l(:button_expand_all)}", + "toggleAllRowGroups(this)", :class => 'toggle-all') %> +
+ <%= check_box_tag("ids[]", issue.id, false, :style => 'display:none;', :id => nil) %> + <%= link_to(issue.id, issue_path(issue)) %> + #{column_content(column, issue)}
+ <% end %> + +<% else %> +

<%= l(:label_no_data) %>

+<% end %> + +<% content_for :header_tags do %> +<%= auto_discovery_link_tag(:atom, + {controller: 'issues', action: 'index', query_id: query.id, project_id: query.project.try(:identifier), + format: 'atom', key: User.current.rss_key}, + {:title => query.name}) %> +<% end %> + diff --git a/app/views/my/page.html.erb b/app/views/my/page.html.erb index 819ddde..bd802f6 100644 --- a/app/views/my/page.html.erb +++ b/app/views/my/page.html.erb @@ -6,27 +6,27 @@
<% @blocks['top'].each do |b| - next unless MyController::BLOCKS.keys.include? b %> + next unless @all_blocks.keys.include? b %>
- <%= render :partial => "my/blocks/#{b}", :locals => { :user => @user } %> + <%= render_mypage_box b %>
<% end if @blocks['top'] %>
<% @blocks['left'].each do |b| - next unless MyController::BLOCKS.keys.include? b %> + next unless @all_blocks.keys.include? b %>
- <%= render :partial => "my/blocks/#{b}", :locals => { :user => @user } %> + <%= render_mypage_box b %>
<% end if @blocks['left'] %>
<% @blocks['right'].each do |b| - next unless MyController::BLOCKS.keys.include? b %> + next unless @all_blocks.keys.include? b %>
- <%= render :partial => "my/blocks/#{b}", :locals => { :user => @user } %> + <%= render_mypage_box b %>
<% end if @blocks['right'] %>
diff --git a/app/views/my/page_layout.html.erb b/app/views/my/page_layout.html.erb index 4a60d97..b066253 100644 --- a/app/views/my/page_layout.html.erb +++ b/app/views/my/page_layout.html.erb @@ -3,7 +3,7 @@ <%= form_tag({:action => "add_block"}, :id => "block-form") do %> <%= label_tag('block-select', l(:label_my_page_block)) %>: <%= select_tag 'block', - content_tag('option') + options_for_select(@block_options), + content_tag('option') + mypage_available_block_options, :id => "block-select" %> <%= link_to l(:button_add), '#', :onclick => '$("#block-form").submit()', :class => 'icon icon-add' %> <% end %> @@ -15,21 +15,21 @@
<% @blocks['top'].each do |b| - next unless MyController::BLOCKS.keys.include? b %> + next unless @all_blocks.keys.include? b %> <%= render :partial => 'block', :locals => {:user => @user, :block_name => b} %> <% end if @blocks['top'] %>
<% @blocks['left'].each do |b| - next unless MyController::BLOCKS.keys.include? b %> + next unless @all_blocks.keys.include? b %> <%= render :partial => 'block', :locals => {:user => @user, :block_name => b} %> <% end if @blocks['left'] %>
<% @blocks['right'].each do |b| - next unless MyController::BLOCKS.keys.include? b %> + next unless @all_blocks.keys.include? b %> <%= render :partial => 'block', :locals => {:user => @user, :block_name => b} %> <% end if @blocks['right'] %>
diff --git a/lib/redmine/views/my_page/block.rb b/lib/redmine/views/my_page/block.rb index b04cfaf..511d31b 100644 --- a/lib/redmine/views/my_page/block.rb +++ b/lib/redmine/views/my_page/block.rb @@ -19,6 +19,14 @@ module Redmine module Views module MyPage module Block + def self.all_blocks + MyController::BLOCKS.merge issue_query_blocks + end + + def self.issue_query_blocks + Hash[IssueQuery.visible.map{|q| ["issue_query_#{q.id}", q.name]}] + end + def self.additional_blocks @@additional_blocks ||= Dir.glob("#{Redmine::Plugin.directory}/*/app/views/my/blocks/_*.{rhtml,erb}").inject({}) do |h,file| name = File.basename(file).split('.').first.gsub(/^_/, '') diff --git a/test/functional/my_controller_test.rb b/test/functional/my_controller_test.rb index 65190e6..f7b42ed 100644 --- a/test/functional/my_controller_test.rb +++ b/test/functional/my_controller_test.rb @@ -19,6 +19,7 @@ require File.expand_path('../../test_helper', __FILE__) class MyControllerTest < ActionController::TestCase fixtures :users, :email_addresses, :user_preferences, :roles, :projects, :members, :member_roles, + :queries, :enabled_modules, :issues, :issue_statuses, :trackers, :enumerations, :custom_fields, :auth_sources def setup @@ -37,6 +38,37 @@ class MyControllerTest < ActionController::TestCase assert_template 'page' end + def test_page_with_custom_query + preferences = User.find(2).pref + issue = Issue.find 1 + issue.update_attribute :tracker_id, 3 + q = IssueQuery.find 4 + + preferences[:my_page_layout] = {'top' => ["issue_query_#{q.id}"]} + preferences.save! + + get :page + assert_response :success + assert_select 'h3', /#{q.name}/ + assert_select 'td.id a', /#{issue.id}/ + assert_select 'td.subject a', /print recipes/ + end + + def test_page_layout_should_remove_inaccessible_query + user = User.find 2 + q = IssueQuery.find 3 + assert !IssueQuery.visible(user).include?(q) + preferences = user.pref + preferences[:my_page_layout] = {'top' => ["issue_query_#{q.id}"]} + preferences.save! + + get :page_layout + assert_response :success + user.reload + preferences = user.pref + assert_equal [], preferences[:my_page_layout]['top'] + end + def test_page_with_timelog_block preferences = User.find(2).pref preferences[:my_page_layout] = {'top' => ['timelog']}