##// END OF EJS Templates
Refactor: makes issue id a regular QueryColumn....
Jean-Philippe Lang -
r11217:9b1ebd6808d2
parent child
Show More
@@ -382,10 +382,10 module IssuesHelper
382
382
383 export = FCSV.generate(:col_sep => l(:general_csv_separator)) do |csv|
383 export = FCSV.generate(:col_sep => l(:general_csv_separator)) do |csv|
384 # csv header fields
384 # csv header fields
385 csv << [ "#" ] + columns.collect {|c| Redmine::CodesetUtil.from_utf8(c.caption.to_s, encoding) }
385 csv << columns.collect {|c| Redmine::CodesetUtil.from_utf8(c.caption.to_s, encoding) }
386 # csv lines
386 # csv lines
387 issues.each do |issue|
387 issues.each do |issue|
388 csv << [ issue.id.to_s ] + columns.collect {|c| Redmine::CodesetUtil.from_utf8(csv_content(c, issue), encoding) }
388 csv << columns.collect {|c| Redmine::CodesetUtil.from_utf8(csv_content(c, issue), encoding) }
389 end
389 end
390 end
390 end
391 export
391 export
@@ -67,7 +67,9 module QueriesHelper
67 when 'Date'
67 when 'Date'
68 format_date(value)
68 format_date(value)
69 when 'Fixnum'
69 when 'Fixnum'
70 if column.name == :done_ratio
70 if column.name == :id
71 link_to value, issue_path(issue)
72 elsif column.name == :done_ratio
71 progress_bar(value, :width => '80px')
73 progress_bar(value, :width => '80px')
72 else
74 else
73 value.to_s
75 value.to_s
@@ -20,6 +20,7 class IssueQuery < Query
20 self.queried_class = Issue
20 self.queried_class = Issue
21
21
22 self.available_columns = [
22 self.available_columns = [
23 QueryColumn.new(:id, :sortable => "#{Issue.table_name}.id", :default_order => 'desc', :caption => '#', :frozen => true),
23 QueryColumn.new(:project, :sortable => "#{Project.table_name}.name", :groupable => true),
24 QueryColumn.new(:project, :sortable => "#{Project.table_name}.name", :groupable => true),
24 QueryColumn.new(:tracker, :sortable => "#{Tracker.table_name}.position", :groupable => true),
25 QueryColumn.new(:tracker, :sortable => "#{Tracker.table_name}.position", :groupable => true),
25 QueryColumn.new(:parent, :sortable => ["#{Issue.table_name}.root_id", "#{Issue.table_name}.lft ASC"], :default_order => 'desc', :caption => :field_parent_issue),
26 QueryColumn.new(:parent, :sortable => ["#{Issue.table_name}.root_id", "#{Issue.table_name}.lft ASC"], :default_order => 'desc', :caption => :field_parent_issue),
@@ -216,10 +217,6 class IssueQuery < Query
216 @available_columns
217 @available_columns
217 end
218 end
218
219
219 def sortable_columns
220 {'id' => "#{Issue.table_name}.id"}.merge(super)
221 end
222
223 def default_columns_names
220 def default_columns_names
224 @default_columns_names ||= begin
221 @default_columns_names ||= begin
225 default_columns = Setting.issue_list_default_columns.map(&:to_sym)
222 default_columns = Setting.issue_list_default_columns.map(&:to_sym)
@@ -28,11 +28,12 class QueryColumn
28 end
28 end
29 self.default_order = options[:default_order]
29 self.default_order = options[:default_order]
30 @inline = options.key?(:inline) ? options[:inline] : true
30 @inline = options.key?(:inline) ? options[:inline] : true
31 @caption_key = options[:caption] || "field_#{name}"
31 @caption_key = options[:caption] || "field_#{name}".to_sym
32 @frozen = options[:frozen]
32 end
33 end
33
34
34 def caption
35 def caption
35 l(@caption_key)
36 @caption_key.is_a?(Symbol) ? l(@caption_key) : @caption_key
36 end
37 end
37
38
38 # Returns true if the column is sortable, otherwise false
39 # Returns true if the column is sortable, otherwise false
@@ -48,6 +49,10 class QueryColumn
48 @inline
49 @inline
49 end
50 end
50
51
52 def frozen?
53 @frozen
54 end
55
51 def value(object)
56 def value(object)
52 object.send name
57 object.send name
53 end
58 end
@@ -382,9 +387,10 class Query < ActiveRecord::Base
382
387
383 def columns
388 def columns
384 # preserve the column_names order
389 # preserve the column_names order
385 (has_default_columns? ? default_columns_names : column_names).collect do |name|
390 cols = (has_default_columns? ? default_columns_names : column_names).collect do |name|
386 available_columns.find { |col| col.name == name }
391 available_columns.find { |col| col.name == name }
387 end.compact
392 end.compact
393 available_columns.select(&:frozen?) | cols
388 end
394 end
389
395
390 def inline_columns
396 def inline_columns
@@ -9,7 +9,6
9 :onclick => 'toggleIssuesSelection(this); return false;',
9 :onclick => 'toggleIssuesSelection(this); return false;',
10 :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}" %>
10 :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}" %>
11 </th>
11 </th>
12 <%= sort_header_tag('id', :caption => '#', :default_order => 'desc') %>
13 <% query.inline_columns.each do |column| %>
12 <% query.inline_columns.each do |column| %>
14 <%= column_header(column) %>
13 <%= column_header(column) %>
15 <% end %>
14 <% end %>
@@ -32,13 +31,12
32 <% end %>
31 <% end %>
33 <tr id="issue-<%= issue.id %>" class="hascontextmenu <%= cycle('odd', 'even') %> <%= issue.css_classes %> <%= level > 0 ? "idnt idnt-#{level}" : nil %>">
32 <tr id="issue-<%= issue.id %>" class="hascontextmenu <%= cycle('odd', 'even') %> <%= issue.css_classes %> <%= level > 0 ? "idnt idnt-#{level}" : nil %>">
34 <td class="checkbox hide-when-print"><%= check_box_tag("ids[]", issue.id, false, :id => nil) %></td>
33 <td class="checkbox hide-when-print"><%= check_box_tag("ids[]", issue.id, false, :id => nil) %></td>
35 <td class="id"><%= link_to issue.id, issue_path(issue) %></td>
36 <%= raw query.inline_columns.map {|column| "<td class=\"#{column.css_classes}\">#{column_content(column, issue)}</td>"}.join %>
34 <%= raw query.inline_columns.map {|column| "<td class=\"#{column.css_classes}\">#{column_content(column, issue)}</td>"}.join %>
37 </tr>
35 </tr>
38 <% @query.block_columns.each do |column|
36 <% @query.block_columns.each do |column|
39 if (text = column_content(column, issue)) && text.present? -%>
37 if (text = column_content(column, issue)) && text.present? -%>
40 <tr class="<%= current_cycle %>">
38 <tr class="<%= current_cycle %>">
41 <td colspan="<%= @query.inline_columns.size + 2 %>" class="<%= column.css_classes %>"><%= text %></td>
39 <td colspan="<%= @query.inline_columns.size + 1 %>" class="<%= column.css_classes %>"><%= text %></td>
42 </tr>
40 </tr>
43 <% end -%>
41 <% end -%>
44 <% end -%>
42 <% end -%>
@@ -4,7 +4,7
4 <%= label_tag "available_columns", l(:description_available_columns) %>
4 <%= label_tag "available_columns", l(:description_available_columns) %>
5 <br />
5 <br />
6 <%= select_tag 'available_columns',
6 <%= select_tag 'available_columns',
7 options_for_select((query.available_inline_columns - query.columns).collect {|column| [column.caption, column.name]}),
7 options_for_select((query.available_inline_columns - query.columns).reject(&:frozen?).collect {|column| [column.caption, column.name]}),
8 :multiple => true, :size => 10, :style => "width:150px",
8 :multiple => true, :size => 10, :style => "width:150px",
9 :ondblclick => "moveOptions(this.form.available_columns, this.form.selected_columns);" %>
9 :ondblclick => "moveOptions(this.form.available_columns, this.form.selected_columns);" %>
10 </td>
10 </td>
@@ -18,7 +18,7
18 <%= label_tag "selected_columns", l(:description_selected_columns) %>
18 <%= label_tag "selected_columns", l(:description_selected_columns) %>
19 <br />
19 <br />
20 <%= select_tag((defined?(tag_name) ? tag_name : 'c[]'),
20 <%= select_tag((defined?(tag_name) ? tag_name : 'c[]'),
21 options_for_select(query.inline_columns.collect {|column| [column.caption, column.name]}),
21 options_for_select((query.inline_columns & query.available_inline_columns).reject(&:frozen?).collect {|column| [column.caption, column.name]}),
22 :id => 'selected_columns', :multiple => true, :size => 10, :style => "width:150px",
22 :id => 'selected_columns', :multiple => true, :size => 10, :style => "width:150px",
23 :ondblclick => "moveOptions(this.form.selected_columns, this.form.available_columns);") %>
23 :ondblclick => "moveOptions(this.form.selected_columns, this.form.available_columns);") %>
24 </td>
24 </td>
@@ -380,7 +380,7 class IssuesControllerTest < ActionController::TestCase
380 assert_equal 'text/csv; header=present', @response.content_type
380 assert_equal 'text/csv; header=present', @response.content_type
381 assert @response.body.starts_with?("#,")
381 assert @response.body.starts_with?("#,")
382 lines = @response.body.chomp.split("\n")
382 lines = @response.body.chomp.split("\n")
383 assert_equal assigns(:query).columns.size + 1, lines[0].split(',').size
383 assert_equal assigns(:query).columns.size, lines[0].split(',').size
384 end
384 end
385
385
386 def test_index_csv_with_project
386 def test_index_csv_with_project
@@ -397,7 +397,7 class IssuesControllerTest < ActionController::TestCase
397 assert_equal 'text/csv; header=present', @response.content_type
397 assert_equal 'text/csv; header=present', @response.content_type
398 assert @response.body.starts_with?("#,")
398 assert @response.body.starts_with?("#,")
399 lines = @response.body.chomp.split("\n")
399 lines = @response.body.chomp.split("\n")
400 assert_equal assigns(:query).columns.size + 2, lines[0].split(',').size
400 assert_equal assigns(:query).columns.size + 1, lines[0].split(',').size
401 end
401 end
402
402
403 def test_index_csv_with_spent_time_column
403 def test_index_csv_with_spent_time_column
@@ -416,9 +416,9 class IssuesControllerTest < ActionController::TestCase
416 assert_response :success
416 assert_response :success
417 assert_not_nil assigns(:issues)
417 assert_not_nil assigns(:issues)
418 assert_equal 'text/csv; header=present', @response.content_type
418 assert_equal 'text/csv; header=present', @response.content_type
419 assert @response.body.starts_with?("#,")
419 assert_match /\A#,/, response.body
420 lines = @response.body.chomp.split("\n")
420 lines = response.body.chomp.split("\n")
421 assert_equal assigns(:query).available_inline_columns.size + 1, lines[0].split(',').size
421 assert_equal assigns(:query).available_inline_columns.size, lines[0].split(',').size
422 end
422 end
423
423
424 def test_index_csv_with_multi_column_field
424 def test_index_csv_with_multi_column_field
@@ -708,12 +708,12 class IssuesControllerTest < ActionController::TestCase
708 # query should use specified columns
708 # query should use specified columns
709 query = assigns(:query)
709 query = assigns(:query)
710 assert_kind_of IssueQuery, query
710 assert_kind_of IssueQuery, query
711 assert_equal [:project, :tracker, :subject, :assigned_to], query.columns.map(&:name)
711 assert_equal [:id, :project, :tracker, :subject, :assigned_to], query.columns.map(&:name)
712 end
712 end
713
713
714 def test_index_without_project_and_explicit_default_columns_should_not_add_project_column
714 def test_index_without_project_and_explicit_default_columns_should_not_add_project_column
715 Setting.issue_list_default_columns = ['tracker', 'subject', 'assigned_to']
715 Setting.issue_list_default_columns = ['tracker', 'subject', 'assigned_to']
716 columns = ['tracker', 'subject', 'assigned_to']
716 columns = ['id', 'tracker', 'subject', 'assigned_to']
717 get :index, :set_filter => 1, :c => columns
717 get :index, :set_filter => 1, :c => columns
718
718
719 # query should use specified columns
719 # query should use specified columns
@@ -114,7 +114,7 class QueriesControllerTest < ActionController::TestCase
114 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => nil, :query_id => q
114 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => nil, :query_id => q
115 assert !q.is_public?
115 assert !q.is_public?
116 assert !q.has_default_columns?
116 assert !q.has_default_columns?
117 assert_equal [:tracker, :subject, :priority, :category], q.columns.collect {|c| c.name}
117 assert_equal [:id, :tracker, :subject, :priority, :category], q.columns.collect {|c| c.name}
118 assert q.valid?
118 assert q.valid?
119 end
119 end
120
120
@@ -750,16 +750,34 class QueryTest < ActiveSupport::TestCase
750 def test_set_column_names
750 def test_set_column_names
751 q = IssueQuery.new
751 q = IssueQuery.new
752 q.column_names = ['tracker', :subject, '', 'unknonw_column']
752 q.column_names = ['tracker', :subject, '', 'unknonw_column']
753 assert_equal [:tracker, :subject], q.columns.collect {|c| c.name}
753 assert_equal [:id, :tracker, :subject], q.columns.collect {|c| c.name}
754 c = q.columns.first
754 end
755 assert q.has_column?(c)
755
756 def test_has_column_should_accept_a_column_name
757 q = IssueQuery.new
758 q.column_names = ['tracker', :subject]
759 assert q.has_column?(:tracker)
760 assert !q.has_column?(:category)
761 end
762
763 def test_has_column_should_accept_a_column
764 q = IssueQuery.new
765 q.column_names = ['tracker', :subject]
766
767 tracker_column = q.available_columns.detect {|c| c.name==:tracker}
768 assert_kind_of QueryColumn, tracker_column
769 category_column = q.available_columns.detect {|c| c.name==:category}
770 assert_kind_of QueryColumn, category_column
771
772 assert q.has_column?(tracker_column)
773 assert !q.has_column?(category_column)
756 end
774 end
757
775
758 def test_inline_and_block_columns
776 def test_inline_and_block_columns
759 q = IssueQuery.new
777 q = IssueQuery.new
760 q.column_names = ['subject', 'description', 'tracker']
778 q.column_names = ['subject', 'description', 'tracker']
761
779
762 assert_equal [:subject, :tracker], q.inline_columns.map(&:name)
780 assert_equal [:id, :subject, :tracker], q.inline_columns.map(&:name)
763 assert_equal [:description], q.block_columns.map(&:name)
781 assert_equal [:description], q.block_columns.map(&:name)
764 end
782 end
765
783
General Comments 0
You need to be logged in to leave comments. Login now