summaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
authorJean-Philippe Lang <jp_lang@yahoo.fr>2017-03-14 18:18:19 +0000
committerJean-Philippe Lang <jp_lang@yahoo.fr>2017-03-14 18:18:19 +0000
commit8c7898bb5db0d29cd418eac3c6e27191cf3571ed (patch)
treeaae5c57d61644de3c1d3786192ce7e2069c23e13 /app
parentb878a427f2928e600ca51d03fc47637fa85cf859 (diff)
downloadredmine-8c7898bb5db0d29cd418eac3c6e27191cf3571ed.tar.gz
redmine-8c7898bb5db0d29cd418eac3c6e27191cf3571ed.zip
Let user choose columns and sort order of issue lists on "My page" (#1565).
git-svn-id: http://svn.redmine.org/redmine/trunk@16400 e93f8b46-1217-0410-a6f0-8f06a7374b81
Diffstat (limited to 'app')
-rw-r--r--app/controllers/my_controller.rb1
-rw-r--r--app/helpers/my_helper.rb55
-rw-r--r--app/helpers/queries_helper.rb18
-rw-r--r--app/models/query.rb16
-rw-r--r--app/models/user_preference.rb1
-rw-r--r--app/views/issues/_list.html.erb5
-rw-r--r--app/views/my/blocks/_issues.erb42
-rw-r--r--app/views/my/blocks/_issuesassignedtome.html.erb15
-rw-r--r--app/views/my/blocks/_issuesreportedbyme.html.erb15
-rw-r--r--app/views/my/blocks/_issueswatched.html.erb9
-rw-r--r--app/views/my/page.html.erb1
-rw-r--r--app/views/queries/_columns.html.erb30
12 files changed, 129 insertions, 79 deletions
diff --git a/app/controllers/my_controller.rb b/app/controllers/my_controller.rb
index 66bd965ba..f0b56e44f 100644
--- a/app/controllers/my_controller.rb
+++ b/app/controllers/my_controller.rb
@@ -27,6 +27,7 @@ class MyController < ApplicationController
helper :issues
helper :users
helper :custom_fields
+ helper :queries
def index
page
diff --git a/app/helpers/my_helper.rb b/app/helpers/my_helper.rb
index 3975d80b1..2a20a7bf2 100644
--- a/app/helpers/my_helper.rb
+++ b/app/helpers/my_helper.rb
@@ -44,16 +44,17 @@ module MyHelper
# Renders a single block content
def render_block_content(block, user)
- unless Redmine::MyPage.blocks.key?(block)
+ unless block_definition = Redmine::MyPage.blocks[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 => "my/blocks/#{block}", :locals => {:user => user, :settings => settings})
+ render(:partial => partial, :locals => {:user => user, :settings => settings, :block => block})
rescue ActionView::MissingTemplate
- Rails.logger.warn("Template missing for block \"#{block}\" found in #{user.login} (id=#{user.id}) preferences")
+ Rails.logger.warn("Partial \"#{partial}\" missing for block \"#{block}\" found in #{user.login} (id=#{user.id}) preferences")
return nil
end
end
@@ -80,30 +81,38 @@ module MyHelper
Document.visible.order("#{Document.table_name}.created_on DESC").limit(10).to_a
end
- def issuesassignedtome_items
- Issue.visible.open.
- assigned_to(User.current).
- limit(10).
- includes(:status, :project, :tracker, :priority).
- references(:status, :project, :tracker, :priority).
- order("#{IssuePriority.table_name}.position DESC, #{Issue.table_name}.updated_on DESC")
+ def issues_items(block, settings)
+ send "#{block}_items", settings
end
- def issuesreportedbyme_items
- Issue.visible.open.
- where(:author_id => User.current.id).
- limit(10).
- includes(:status, :project, :tracker, :priority).
- references(:status, :project, :tracker).
- order("#{Issue.table_name}.updated_on DESC")
+ def issuesassignedtome_items(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
end
- def issueswatched_items
- Issue.visible.open.
- on_active_project.watched_by(User.current.id).
- preload(:status, :project, :tracker, :priority).
- recently_updated.
- limit(10)
+ def issuesreportedbyme_items(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
+ end
+
+ def issueswatched_items(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
end
def news_items
diff --git a/app/helpers/queries_helper.rb b/app/helpers/queries_helper.rb
index 1d0db2877..b4a0a0b75 100644
--- a/app/helpers/queries_helper.rb
+++ b/app/helpers/queries_helper.rb
@@ -161,7 +161,7 @@ module QueriesHelper
content_tag('span', label + " " + value, :class => "total-for-#{column.name.to_s.dasherize}")
end
- def column_header(query, column)
+ def column_header(query, column, options={})
if column.sortable?
css, order = nil, column.default_order
if column.name.to_s == query.sort_criteria.first_key
@@ -173,11 +173,21 @@ module QueriesHelper
order = 'asc'
end
end
- sort_param = { :sort => query.sort_criteria.add(column.name, order).to_param }
- content = link_to(column.caption,
- {:params => request.query_parameters.merge(sort_param)},
+ param_key = options[:sort_param] || :sort
+ sort_param = { param_key => query.sort_criteria.add(column.name, order).to_param }
+ while sort_param.keys.first.to_s =~ /^(.+)\[(.+)\]$/
+ sort_param = {$1 => {$2 => sort_param.values.first}}
+ end
+ link_options = {
:title => l(:label_sort_by, "\"#{column.caption}\""),
:class => css
+ }
+ if options[:sort_link_options]
+ link_options.merge! options[:sort_link_options]
+ end
+ content = link_to(column.caption,
+ {:params => request.query_parameters.deep_merge(sort_param)},
+ link_options
)
else
content = column.caption
diff --git a/app/models/query.rb b/app/models/query.rb
index 192502024..23eca0278 100644
--- a/app/models/query.rb
+++ b/app/models/query.rb
@@ -386,6 +386,22 @@ class Query < ActiveRecord::Base
new(attributes).build_from_params(params)
end
+ def as_params
+ params = {}
+ filters.each do |field, options|
+ params[:f] ||= []
+ params[:f] << field
+ params[:op] ||= {}
+ params[:op][field] = options[:operator]
+ params[:v] ||= {}
+ params[:v][field] = options[:values]
+ end
+ params[:c] = column_names
+ params[:sort] = sort_criteria.to_param
+ params[:set_filter] = 1
+ params
+ end
+
def validate_query_filters
filters.each_key do |field|
if values_for(field)
diff --git a/app/models/user_preference.rb b/app/models/user_preference.rb
index 41c0f0b4b..0ebafa839 100644
--- a/app/models/user_preference.rb
+++ b/app/models/user_preference.rb
@@ -128,6 +128,7 @@ class UserPreference < ActiveRecord::Base
end
def update_block_settings(block, settings)
+ block = block.to_s
block_settings = my_page_settings(block).merge(settings.symbolize_keys)
my_page_settings[block] = block_settings
end
diff --git a/app/views/issues/_list.html.erb b/app/views/issues/_list.html.erb
index f9172143b..5488fb295 100644
--- a/app/views/issues/_list.html.erb
+++ b/app/views/issues/_list.html.erb
@@ -1,3 +1,6 @@
+<% query_options = nil unless defined?(query_options) %>
+<% query_options ||= {} %>
+
<%= form_tag({}, :data => {:cm_url => issues_context_menu_path}) do -%>
<%= hidden_field_tag 'back_url', url_for(:params => request.query_parameters), :id => nil %>
<div class="autoscroll">
@@ -9,7 +12,7 @@
:title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}" %>
</th>
<% query.inline_columns.each do |column| %>
- <%= column_header(query, column) %>
+ <%= column_header(query, column, query_options) %>
<% end %>
</tr>
</thead>
diff --git a/app/views/my/blocks/_issues.erb b/app/views/my/blocks/_issues.erb
new file mode 100644
index 000000000..bbd10af33
--- /dev/null
+++ b/app/views/my/blocks/_issues.erb
@@ -0,0 +1,42 @@
+<% issues, query = issues_items(block, settings) %>
+
+<div class="contextual">
+ <%= link_to_function l(:label_options), "$('##{block}-settings').toggle();", :class => 'icon-only icon-settings' %>
+</div>
+
+<h3>
+ <%= link_to query.name, issues_path(query.as_params) %>
+ (<%= query.issue_count %>)
+</h3>
+
+<div id="<%= block %>-settings" style="display:none;">
+ <%= form_tag(my_page_path, :remote => true) do %>
+ <div class="box">
+ <%= render_query_columns_selection(query, :name => "settings[#{block}][columns]") %>
+ </div>
+ <p>
+ <%= submit_tag l(:button_save) %>
+ <%= link_to_function l(:button_cancel), "$('##{block}-settings').toggle();" %>
+ </p>
+ <% end %>
+</div>
+
+<% if issues.any? %>
+ <%= render :partial => 'issues/list',
+ :locals => {
+ :issues => issues,
+ :query => query,
+ :query_options => {
+ :sort_param => "settings[#{block}][sort]",
+ :sort_link_options => {:method => :post, :remote => true}
+ }
+ } %>
+<% else %>
+ <p class="nodata"><%= l(:label_no_data) %></p>
+<% end %>
+
+<% content_for :header_tags do %>
+<%= auto_discovery_link_tag(:atom,
+ issues_path(query.as_params.merge(:format => 'atom', :key => User.current.rss_key)),
+ {:title => query.name}) %>
+<% end %>
diff --git a/app/views/my/blocks/_issuesassignedtome.html.erb b/app/views/my/blocks/_issuesassignedtome.html.erb
deleted file mode 100644
index 94948b7aa..000000000
--- a/app/views/my/blocks/_issuesassignedtome.html.erb
+++ /dev/null
@@ -1,15 +0,0 @@
-<% assigned_issues = issuesassignedtome_items %>
-<h3>
- <%= link_to l(:label_assigned_to_me_issues),
- issues_path(:set_filter => 1, :assigned_to_id => 'me', :sort => 'priority:desc,updated_on:desc') %>
- (<%= assigned_issues.limit(nil).count %>)
-</h3>
-
-<%= render :partial => 'issues/list_simple', :locals => { :issues => assigned_issues.to_a } %>
-
-<% content_for :header_tags do %>
-<%= auto_discovery_link_tag(:atom,
- {:controller => 'issues', :action => 'index', :set_filter => 1,
- :assigned_to_id => 'me', :format => 'atom', :key => User.current.rss_key},
- {:title => l(:label_assigned_to_me_issues)}) %>
-<% end %>
diff --git a/app/views/my/blocks/_issuesreportedbyme.html.erb b/app/views/my/blocks/_issuesreportedbyme.html.erb
deleted file mode 100644
index 91557c035..000000000
--- a/app/views/my/blocks/_issuesreportedbyme.html.erb
+++ /dev/null
@@ -1,15 +0,0 @@
-<% reported_issues = issuesreportedbyme_items %>
-<h3>
- <%= link_to l(:label_reported_issues),
- issues_path(:set_filter => 1, :status_id => 'o', :author_id => 'me', :sort => 'updated_on:desc') %>
- (<%= reported_issues.limit(nil).count %>)
-</h3>
-
-<%= render :partial => 'issues/list_simple', :locals => { :issues => reported_issues.to_a } %>
-
-<% content_for :header_tags do %>
-<%= auto_discovery_link_tag(:atom,
- {:controller => 'issues', :action => 'index', :set_filter => 1,
- :author_id => 'me', :format => 'atom', :key => User.current.rss_key},
- {:title => l(:label_reported_issues)}) %>
-<% end %>
diff --git a/app/views/my/blocks/_issueswatched.html.erb b/app/views/my/blocks/_issueswatched.html.erb
deleted file mode 100644
index 512a52238..000000000
--- a/app/views/my/blocks/_issueswatched.html.erb
+++ /dev/null
@@ -1,9 +0,0 @@
-<% watched_issues = issueswatched_items %>
-<h3>
- <%= link_to l(:label_watched_issues),
- issues_path(:set_filter => 1, :watcher_id => 'me', :sort => 'updated_on:desc') %>
- (<%= watched_issues.limit(nil).count %>)
-</h3>
-
-
-<%= render :partial => 'issues/list_simple', :locals => { :issues => watched_issues.to_a } %>
diff --git a/app/views/my/page.html.erb b/app/views/my/page.html.erb
index 1210c471a..7f67d0a90 100644
--- a/app/views/my/page.html.erb
+++ b/app/views/my/page.html.erb
@@ -25,6 +25,7 @@
<%= javascript_tag do %>
$(document).ready(function(){
+ $('#block-select').val('');
$('#list-top, #list-left, #list-right').sortable({
connectWith: '.block-receiver',
tolerance: 'pointer',
diff --git a/app/views/queries/_columns.html.erb b/app/views/queries/_columns.html.erb
index d102341c1..26a460780 100644
--- a/app/views/queries/_columns.html.erb
+++ b/app/views/queries/_columns.html.erb
@@ -1,32 +1,38 @@
+<% tag_id = tag_name.gsub(/[\[\]]+/, '_').sub(/_+$/, '') %>
+<% available_tag_id = "available_#{tag_id}" %>
+<% selected_tag_id = "selected_#{tag_id}" %>
+
<table class="query-columns">
<tr>
<td style="padding-left:0">
- <%= label_tag "available_columns", l(:description_available_columns) %>
+ <%= label_tag available_tag_id, l(:description_available_columns) %>
<br />
<%= select_tag 'available_columns',
options_for_select(query_available_inline_columns_options(query)),
+ :id => available_tag_id,
:multiple => true, :size => 10, :style => "width:150px",
- :ondblclick => "moveOptions(this.form.available_columns, this.form.selected_columns);" %>
+ :ondblclick => "moveOptions(this.form.#{available_tag_id}, this.form.#{selected_tag_id});" %>
</td>
<td class="buttons">
<input type="button" value="&#8594;"
- onclick="moveOptions(this.form.available_columns, this.form.selected_columns);" /><br />
+ onclick="moveOptions(this.form.<%= available_tag_id %>, this.form.<%= selected_tag_id %>);" /><br />
<input type="button" value="&#8592;"
- onclick="moveOptions(this.form.selected_columns, this.form.available_columns);" />
+ onclick="moveOptions(this.form.<%= selected_tag_id %>, this.form.<%= available_tag_id %>);" />
</td>
<td>
- <%= label_tag "selected_columns", l(:description_selected_columns) %>
+ <%= label_tag selected_tag_id, l(:description_selected_columns) %>
<br />
<%= select_tag tag_name,
options_for_select(query_selected_inline_columns_options(query)),
- :id => 'selected_columns', :multiple => true, :size => 10, :style => "width:150px",
- :ondblclick => "moveOptions(this.form.selected_columns, this.form.available_columns);" %>
+ :id => selected_tag_id,
+ :multiple => true, :size => 10, :style => "width:150px",
+ :ondblclick => "moveOptions(this.form.#{selected_tag_id}, this.form.#{available_tag_id});" %>
</td>
<td class="buttons">
- <input type="button" value="&#8648;" onclick="moveOptionTop(this.form.selected_columns);" /><br />
- <input type="button" value="&#8593;" onclick="moveOptionUp(this.form.selected_columns);" /><br />
- <input type="button" value="&#8595;" onclick="moveOptionDown(this.form.selected_columns);" /><br />
- <input type="button" value="&#8650;" onclick="moveOptionBottom(this.form.selected_columns);" />
+ <input type="button" value="&#8648;" onclick="moveOptionTop(this.form.<%= selected_tag_id %>);" /><br />
+ <input type="button" value="&#8593;" onclick="moveOptionUp(this.form.<%= selected_tag_id %>);" /><br />
+ <input type="button" value="&#8595;" onclick="moveOptionDown(this.form.<%= selected_tag_id %>);" /><br />
+ <input type="button" value="&#8650;" onclick="moveOptionBottom(this.form.<%= selected_tag_id %>);" />
</td>
</tr>
</table>
@@ -34,7 +40,7 @@
<%= javascript_tag do %>
$(document).ready(function(){
$('.query-columns').closest('form').submit(function(){
- $('#selected_columns option').prop('selected', true);
+ $('#<%= selected_tag_id %> option').prop('selected', true);
});
});
<% end %>