mirror of
https://github.com/meineerde/redmine.git
synced 2026-01-08 00:21:31 +00:00
Allow multiple instances of custom queries on My page (#1565).
git-svn-id: http://svn.redmine.org/redmine/trunk@16413 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
parent
1a180a67be
commit
4cfd513373
@ -47,26 +47,29 @@ module MyHelper
|
||||
|
||||
# Renders a single block content
|
||||
def render_block_content(block, user)
|
||||
unless block_definition = Redmine::MyPage.blocks[block]
|
||||
unless block_definition = Redmine::MyPage.find_block(block)
|
||||
Rails.logger.warn("Unknown block \"#{block}\" found in #{user.login} (id=#{user.id}) preferences")
|
||||
return
|
||||
end
|
||||
|
||||
settings = user.pref.my_page_settings(block)
|
||||
partial = block_definition[:partial]
|
||||
begin
|
||||
render(:partial => partial, :locals => {:user => user, :settings => settings, :block => block})
|
||||
rescue ActionView::MissingTemplate
|
||||
Rails.logger.warn("Partial \"#{partial}\" missing for block \"#{block}\" found in #{user.login} (id=#{user.id}) preferences")
|
||||
return nil
|
||||
if partial = block_definition[:partial]
|
||||
begin
|
||||
render(:partial => partial, :locals => {:user => user, :settings => settings, :block => block})
|
||||
rescue ActionView::MissingTemplate
|
||||
Rails.logger.warn("Partial \"#{partial}\" missing for block \"#{block}\" found in #{user.login} (id=#{user.id}) preferences")
|
||||
return nil
|
||||
end
|
||||
else
|
||||
send "render_#{block_definition[:name]}_block", block, settings
|
||||
end
|
||||
end
|
||||
|
||||
def block_select_tag(user)
|
||||
disabled = user.pref.my_page_layout.values.flatten
|
||||
blocks_in_use = user.pref.my_page_layout.values.flatten
|
||||
options = content_tag('option')
|
||||
Redmine::MyPage.block_options.each do |label, block|
|
||||
options << content_tag('option', label, :value => block, :disabled => disabled.include?(block))
|
||||
Redmine::MyPage.block_options(blocks_in_use).each do |label, block|
|
||||
options << content_tag('option', label, :value => block, :disabled => block.blank?)
|
||||
end
|
||||
select_tag('block', options, :id => "block-select", :onchange => "$('#block-form').submit();")
|
||||
end
|
||||
@ -88,45 +91,47 @@ module MyHelper
|
||||
send "#{block}_items", settings
|
||||
end
|
||||
|
||||
def issuesassignedtome_items(settings)
|
||||
def render_issuesassignedtome_block(block, settings)
|
||||
query = IssueQuery.new(:name => l(:label_assigned_to_me_issues), :user => User.current)
|
||||
query.add_filter 'assigned_to_id', '=', ['me']
|
||||
query.column_names = settings[:columns].presence || ['project', 'tracker', 'status', 'subject']
|
||||
query.sort_criteria = settings[:sort].presence || [['priority', 'desc'], ['updated_on', 'desc']]
|
||||
issues = query.issues(:limit => 10)
|
||||
|
||||
return issues, query
|
||||
render :partial => 'my/blocks/issues', :locals => {:query => query, :issues => issues, :block => block}
|
||||
end
|
||||
|
||||
def issuesreportedbyme_items(settings)
|
||||
def render_issuesreportedbyme_block(block, settings)
|
||||
query = IssueQuery.new(:name => l(:label_reported_issues), :user => User.current)
|
||||
query.add_filter 'author_id', '=', ['me']
|
||||
query.column_names = settings[:columns].presence || ['project', 'tracker', 'status', 'subject']
|
||||
query.sort_criteria = settings[:sort].presence || [['updated_on', 'desc']]
|
||||
issues = query.issues(:limit => 10)
|
||||
|
||||
return issues, query
|
||||
render :partial => 'my/blocks/issues', :locals => {:query => query, :issues => issues, :block => block}
|
||||
end
|
||||
|
||||
def issueswatched_items(settings)
|
||||
def render_issueswatched_block(block, settings)
|
||||
query = IssueQuery.new(:name => l(:label_watched_issues), :user => User.current)
|
||||
query.add_filter 'watcher_id', '=', ['me']
|
||||
query.column_names = settings[:columns].presence || ['project', 'tracker', 'status', 'subject']
|
||||
query.sort_criteria = settings[:sort].presence || [['updated_on', 'desc']]
|
||||
issues = query.issues(:limit => 10)
|
||||
|
||||
return issues, query
|
||||
render :partial => 'my/blocks/issues', :locals => {:query => query, :issues => issues, :block => block}
|
||||
end
|
||||
|
||||
def issuequery_items(settings)
|
||||
def render_issuequery_block(block, settings)
|
||||
query = IssueQuery.visible.find_by_id(settings[:query_id])
|
||||
return unless query
|
||||
|
||||
query.column_names = settings[:columns] if settings[:columns].present?
|
||||
query.sort_criteria = settings[:sort] if settings[:sort].present?
|
||||
issues = query.issues(:limit => 10)
|
||||
|
||||
return issues, query
|
||||
if query
|
||||
query.column_names = settings[:columns] if settings[:columns].present?
|
||||
query.sort_criteria = settings[:sort] if settings[:sort].present?
|
||||
issues = query.issues(:limit => 10)
|
||||
render :partial => 'my/blocks/issues', :locals => {:query => query, :issues => issues, :block => block, :settings => settings}
|
||||
else
|
||||
render :partial => 'my/blocks/issue_query_selection', :locals => {:block => block, :settings => settings}
|
||||
end
|
||||
end
|
||||
|
||||
def news_items
|
||||
|
||||
@ -109,6 +109,7 @@ class UserPreference < ActiveRecord::Base
|
||||
self[:my_page_settings] = arg
|
||||
end
|
||||
|
||||
# Removes block from the user page layout
|
||||
def remove_block(block)
|
||||
block = block.to_s.underscore
|
||||
%w(top left right).each do |f|
|
||||
@ -117,9 +118,12 @@ class UserPreference < ActiveRecord::Base
|
||||
my_page_layout
|
||||
end
|
||||
|
||||
# Adds block to the user page layout
|
||||
# Returns nil if block is not valid or if it's already
|
||||
# present in the user page layout
|
||||
def add_block(block)
|
||||
block = block.to_s.underscore
|
||||
return unless Redmine::MyPage.blocks.key?(block)
|
||||
return unless Redmine::MyPage.valid_block?(block, my_page_layout.values.flatten)
|
||||
|
||||
remove_block(block)
|
||||
# add it on top
|
||||
|
||||
21
app/views/my/blocks/_issue_query_selection.html.erb
Normal file
21
app/views/my/blocks/_issue_query_selection.html.erb
Normal file
@ -0,0 +1,21 @@
|
||||
<% visible_queries = IssueQuery.visible.sorted %>
|
||||
|
||||
<h3>
|
||||
<%= l(:label_issue_plural) %>
|
||||
</h3>
|
||||
|
||||
<div id="<%= block %>-settings">
|
||||
<%= form_tag(my_page_path, :remote => true) do %>
|
||||
<div class="box">
|
||||
<p>
|
||||
<label>
|
||||
<%= l(:label_query) %>
|
||||
<%= select_tag "settings[#{block}][query_id]", content_tag("option") + options_from_collection_for_select(visible_queries, :id, :name, settings[:query_id]) %>
|
||||
</label>
|
||||
</p>
|
||||
</div>
|
||||
<p>
|
||||
<%= submit_tag l(:button_save) %>
|
||||
</p>
|
||||
<% end %>
|
||||
</div>
|
||||
@ -1,6 +1,3 @@
|
||||
<% issues, query = issues_items(block, settings) %>
|
||||
|
||||
<% if query %>
|
||||
<div class="contextual">
|
||||
<%= link_to_function l(:label_options), "$('##{block}-settings').toggle();", :class => 'icon-only icon-settings', :title => l(:label_options) %>
|
||||
</div>
|
||||
@ -42,28 +39,3 @@
|
||||
_project_issues_path(query.project, query.as_params.merge(:format => 'atom', :key => User.current.rss_key)),
|
||||
{:title => query.name}) %>
|
||||
<% end %>
|
||||
|
||||
<% else %>
|
||||
<% visible_queries = IssueQuery.visible.sorted %>
|
||||
|
||||
<h3>
|
||||
<%= l(:label_issue_plural) %>
|
||||
</h3>
|
||||
|
||||
<div id="<%= block %>-settings">
|
||||
<%= form_tag(my_page_path, :remote => true) do %>
|
||||
<div class="box">
|
||||
<p>
|
||||
<label>
|
||||
<%= l(:label_query) %>
|
||||
<%= select_tag 'settings[issuequery][query_id]', content_tag("option") + options_from_collection_for_select(visible_queries, :id, :name, settings[:query_id]) %>
|
||||
</label>
|
||||
</p>
|
||||
</div>
|
||||
<p>
|
||||
<%= submit_tag l(:button_save) %>
|
||||
</p>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<% end %>
|
||||
|
||||
@ -20,10 +20,10 @@ module Redmine
|
||||
include Redmine::I18n
|
||||
|
||||
CORE_BLOCKS = {
|
||||
'issuesassignedtome' => {:label => :label_assigned_to_me_issues, :partial => 'my/blocks/issues'},
|
||||
'issuesreportedbyme' => {:label => :label_reported_issues, :partial => 'my/blocks/issues'},
|
||||
'issueswatched' => {:label => :label_watched_issues, :partial => 'my/blocks/issues'},
|
||||
'issuequery' => {:label => :label_issue_plural, :partial => 'my/blocks/issues'},
|
||||
'issuesassignedtome' => {:label => :label_assigned_to_me_issues},
|
||||
'issuesreportedbyme' => {:label => :label_reported_issues},
|
||||
'issueswatched' => {:label => :label_watched_issues},
|
||||
'issuequery' => {:label => :label_issue_plural, :max_occurs => 3},
|
||||
'news' => {:label => :label_news_latest, :partial => 'my/blocks/news'},
|
||||
'calendar' => {:label => :label_calendar, :partial => 'my/blocks/calendar'},
|
||||
'documents' => {:label => :label_document_plural, :partial => 'my/blocks/documents'},
|
||||
@ -35,15 +35,36 @@ module Redmine
|
||||
CORE_BLOCKS.merge(additional_blocks).freeze
|
||||
end
|
||||
|
||||
def self.block_options
|
||||
def self.block_options(blocks_in_use=[])
|
||||
options = []
|
||||
blocks.each do |block, block_options|
|
||||
indexes = blocks_in_use.map {|n|
|
||||
if n =~ /\A#{block}(__(\d+))?\z/
|
||||
$2.to_i
|
||||
end
|
||||
}.compact
|
||||
|
||||
occurs = indexes.size
|
||||
block_id = indexes.any? ? "#{block}__#{indexes.max + 1}" : block
|
||||
disabled = (occurs >= (Redmine::MyPage.blocks[block][:max_occurs] || 1))
|
||||
block_id = nil if disabled
|
||||
|
||||
label = block_options[:label]
|
||||
options << [l("my.blocks.#{label}", :default => [label, label.to_s.humanize]), block.dasherize]
|
||||
options << [l("my.blocks.#{label}", :default => [label, label.to_s.humanize]), block_id]
|
||||
end
|
||||
options
|
||||
end
|
||||
|
||||
def self.valid_block?(block, blocks_in_use=[])
|
||||
block.present? && block_options(blocks_in_use).map(&:last).include?(block)
|
||||
end
|
||||
|
||||
def self.find_block(block)
|
||||
block.to_s =~ /\A(.*?)(__\d+)?\z/
|
||||
name = $1
|
||||
blocks.has_key?(name) ? blocks[name].merge(:name => name) : nil
|
||||
end
|
||||
|
||||
# Returns the additional blocks that are defined by plugin partials
|
||||
def self.additional_blocks
|
||||
@@additional_blocks ||= Dir.glob("#{Redmine::Plugin.directory}/*/app/views/my/blocks/_*.{rhtml,erb}").inject({}) do |h,file|
|
||||
|
||||
@ -165,6 +165,35 @@ class MyControllerTest < Redmine::ControllerTest
|
||||
end
|
||||
end
|
||||
|
||||
def test_page_with_multiple_issuequery_blocks
|
||||
user = User.find(2)
|
||||
query1 = IssueQuery.create!(:name => 'All issues', :user => user, :column_names => [:tracker, :subject, :status, :assigned_to])
|
||||
query2 = IssueQuery.create!(:name => 'Other issues', :user => user, :column_names => [:tracker, :subject, :priority])
|
||||
user.pref.my_page_layout = {'top' => ['issuequery__1', 'issuequery']}
|
||||
user.pref.my_page_settings = {
|
||||
'issuequery' => {:query_id => query1.id, :columns => [:subject, :due_date]},
|
||||
'issuequery__1' => {:query_id => query2.id}
|
||||
}
|
||||
user.pref.save!
|
||||
|
||||
get :page
|
||||
assert_response :success
|
||||
|
||||
assert_select '#block-issuequery' do
|
||||
assert_select 'h3', :text => /All issues/
|
||||
assert_select 'table.issues th', :text => 'Due date'
|
||||
end
|
||||
|
||||
assert_select '#block-issuequery__1' do
|
||||
assert_select 'h3', :text => /Other issues/
|
||||
assert_select 'table.issues th', :text => 'Priority'
|
||||
end
|
||||
|
||||
assert_select '#block-select' do
|
||||
assert_select 'option[value=?]:not([disabled])', 'issuequery__2', :text => 'Issues'
|
||||
end
|
||||
end
|
||||
|
||||
def test_page_with_all_blocks
|
||||
blocks = Redmine::MyPage.blocks.keys
|
||||
preferences = User.find(2).pref
|
||||
@ -348,15 +377,15 @@ class MyControllerTest < Redmine::ControllerTest
|
||||
end
|
||||
|
||||
def test_add_block
|
||||
post :add_block, :block => 'issuesreportedbyme'
|
||||
post :add_block, :block => 'issueswatched'
|
||||
assert_redirected_to '/my/page'
|
||||
assert User.find(2).pref[:my_page_layout]['top'].include?('issuesreportedbyme')
|
||||
assert User.find(2).pref[:my_page_layout]['top'].include?('issueswatched')
|
||||
end
|
||||
|
||||
def test_add_block_xhr
|
||||
xhr :post, :add_block, :block => 'issuesreportedbyme'
|
||||
xhr :post, :add_block, :block => 'issueswatched'
|
||||
assert_response :success
|
||||
assert_include 'issuesreportedbyme', User.find(2).pref[:my_page_layout]['top']
|
||||
assert_include 'issueswatched', User.find(2).pref[:my_page_layout]['top']
|
||||
end
|
||||
|
||||
def test_add_invalid_block_should_error
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user