##// END OF EJS Templates
Adds helpers for query columns selection....
Jean-Philippe Lang -
r11221:1ac8fd8c4214
parent child
Show More
@@ -1,71 +1,73
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2013 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class SettingsController < ApplicationController
19 19 layout 'admin'
20 20 menu_item :plugins, :only => :plugin
21 21
22 helper :queries
23
22 24 before_filter :require_admin
23 25
24 26 def index
25 27 edit
26 28 render :action => 'edit'
27 29 end
28 30
29 31 def edit
30 32 @notifiables = Redmine::Notifiable.all
31 33 if request.post? && params[:settings] && params[:settings].is_a?(Hash)
32 34 settings = (params[:settings] || {}).dup.symbolize_keys
33 35 settings.each do |name, value|
34 36 # remove blank values in array settings
35 37 value.delete_if {|v| v.blank? } if value.is_a?(Array)
36 38 Setting[name] = value
37 39 end
38 40 flash[:notice] = l(:notice_successful_update)
39 41 redirect_to settings_path(:tab => params[:tab])
40 42 else
41 43 @options = {}
42 44 user_format = User::USER_FORMATS.collect{|key, value| [key, value[:setting_order]]}.sort{|a, b| a[1] <=> b[1]}
43 45 @options[:user_format] = user_format.collect{|f| [User.current.name(f[0]), f[0].to_s]}
44 46 @deliveries = ActionMailer::Base.perform_deliveries
45 47
46 48 @guessed_host_and_path = request.host_with_port.dup
47 49 @guessed_host_and_path << ('/'+ Redmine::Utils.relative_url_root.gsub(%r{^\/}, '')) unless Redmine::Utils.relative_url_root.blank?
48 50
49 51 Redmine::Themes.rescan
50 52 end
51 53 end
52 54
53 55 def plugin
54 56 @plugin = Redmine::Plugin.find(params[:id])
55 57 unless @plugin.configurable?
56 58 render_404
57 59 return
58 60 end
59 61
60 62 if request.post?
61 63 Setting.send "plugin_#{@plugin.id}=", params[:settings]
62 64 flash[:notice] = l(:notice_successful_update)
63 65 redirect_to plugin_settings_path(@plugin)
64 66 else
65 67 @partial = @plugin.settings[:partial]
66 68 @settings = Setting.send "plugin_#{@plugin.id}"
67 69 end
68 70 rescue Redmine::PluginNotFound
69 71 render_404
70 72 end
71 73 end
@@ -1,186 +1,194
1 1 # encoding: utf-8
2 2 #
3 3 # Redmine - project management software
4 4 # Copyright (C) 2006-2013 Jean-Philippe Lang
5 5 #
6 6 # This program is free software; you can redistribute it and/or
7 7 # modify it under the terms of the GNU General Public License
8 8 # as published by the Free Software Foundation; either version 2
9 9 # of the License, or (at your option) any later version.
10 10 #
11 11 # This program is distributed in the hope that it will be useful,
12 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 14 # GNU General Public License for more details.
15 15 #
16 16 # You should have received a copy of the GNU General Public License
17 17 # along with this program; if not, write to the Free Software
18 18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 19
20 20 module QueriesHelper
21 21 def filters_options_for_select(query)
22 22 options_for_select(filters_options(query))
23 23 end
24 24
25 25 def filters_options(query)
26 26 options = [[]]
27 27 options += query.available_filters.map do |field, field_options|
28 28 [field_options[:name], field]
29 29 end
30 30 end
31 31
32 32 def available_block_columns_tags(query)
33 33 tags = ''.html_safe
34 34 query.available_block_columns.each do |column|
35 35 tags << content_tag('label', check_box_tag('c[]', column.name.to_s, query.has_column?(column)) + " #{column.caption}", :class => 'inline')
36 36 end
37 37 tags
38 38 end
39 39
40 def query_available_inline_columns_options(query)
41 (query.available_inline_columns - query.columns).reject(&:frozen?).collect {|column| [column.caption, column.name]}
42 end
43
44 def query_selected_inline_columns_options(query)
45 (query.inline_columns & query.available_inline_columns).reject(&:frozen?).collect {|column| [column.caption, column.name]}
46 end
47
40 48 def column_header(column)
41 49 column.sortable ? sort_header_tag(column.name.to_s, :caption => column.caption,
42 50 :default_order => column.default_order) :
43 51 content_tag('th', h(column.caption))
44 52 end
45 53
46 54 def column_content(column, issue)
47 55 value = column.value(issue)
48 56 if value.is_a?(Array)
49 57 value.collect {|v| column_value(column, issue, v)}.compact.join(', ').html_safe
50 58 else
51 59 column_value(column, issue, value)
52 60 end
53 61 end
54 62
55 63 def column_value(column, issue, value)
56 64 case value.class.name
57 65 when 'String'
58 66 if column.name == :subject
59 67 link_to(h(value), :controller => 'issues', :action => 'show', :id => issue)
60 68 elsif column.name == :description
61 69 issue.description? ? content_tag('div', textilizable(issue, :description), :class => "wiki") : ''
62 70 else
63 71 h(value)
64 72 end
65 73 when 'Time'
66 74 format_time(value)
67 75 when 'Date'
68 76 format_date(value)
69 77 when 'Fixnum'
70 78 if column.name == :id
71 79 link_to value, issue_path(issue)
72 80 elsif column.name == :done_ratio
73 81 progress_bar(value, :width => '80px')
74 82 else
75 83 value.to_s
76 84 end
77 85 when 'Float'
78 86 sprintf "%.2f", value
79 87 when 'User'
80 88 link_to_user value
81 89 when 'Project'
82 90 link_to_project value
83 91 when 'Version'
84 92 link_to(h(value), :controller => 'versions', :action => 'show', :id => value)
85 93 when 'TrueClass'
86 94 l(:general_text_Yes)
87 95 when 'FalseClass'
88 96 l(:general_text_No)
89 97 when 'Issue'
90 98 value.visible? ? link_to_issue(value) : "##{value.id}"
91 99 when 'IssueRelation'
92 100 other = value.other_issue(issue)
93 101 content_tag('span',
94 102 (l(value.label_for(issue)) + " " + link_to_issue(other, :subject => false, :tracker => false)).html_safe,
95 103 :class => value.css_classes_for(issue))
96 104 else
97 105 h(value)
98 106 end
99 107 end
100 108
101 109 def csv_content(column, issue)
102 110 value = column.value(issue)
103 111 if value.is_a?(Array)
104 112 value.collect {|v| csv_value(column, issue, v)}.compact.join(', ')
105 113 else
106 114 csv_value(column, issue, value)
107 115 end
108 116 end
109 117
110 118 def csv_value(column, issue, value)
111 119 case value.class.name
112 120 when 'Time'
113 121 format_time(value)
114 122 when 'Date'
115 123 format_date(value)
116 124 when 'Float'
117 125 sprintf("%.2f", value).gsub('.', l(:general_csv_decimal_separator))
118 126 when 'IssueRelation'
119 127 other = value.other_issue(issue)
120 128 l(value.label_for(issue)) + " ##{other.id}"
121 129 else
122 130 value.to_s
123 131 end
124 132 end
125 133
126 134 def query_to_csv(items, query, options={})
127 135 encoding = l(:general_csv_encoding)
128 136 columns = (options[:columns] == 'all' ? query.available_inline_columns : query.inline_columns)
129 137 query.available_block_columns.each do |column|
130 138 if options[column.name].present?
131 139 columns << column
132 140 end
133 141 end
134 142
135 143 export = FCSV.generate(:col_sep => l(:general_csv_separator)) do |csv|
136 144 # csv header fields
137 145 csv << columns.collect {|c| Redmine::CodesetUtil.from_utf8(c.caption.to_s, encoding) }
138 146 # csv lines
139 147 items.each do |item|
140 148 csv << columns.collect {|c| Redmine::CodesetUtil.from_utf8(csv_content(c, item), encoding) }
141 149 end
142 150 end
143 151 export
144 152 end
145 153
146 154 # Retrieve query from session or build a new query
147 155 def retrieve_query
148 156 if !params[:query_id].blank?
149 157 cond = "project_id IS NULL"
150 158 cond << " OR project_id = #{@project.id}" if @project
151 159 @query = IssueQuery.find(params[:query_id], :conditions => cond)
152 160 raise ::Unauthorized unless @query.visible?
153 161 @query.project = @project
154 162 session[:query] = {:id => @query.id, :project_id => @query.project_id}
155 163 sort_clear
156 164 elsif api_request? || params[:set_filter] || session[:query].nil? || session[:query][:project_id] != (@project ? @project.id : nil)
157 165 # Give it a name, required to be valid
158 166 @query = IssueQuery.new(:name => "_")
159 167 @query.project = @project
160 168 @query.build_from_params(params)
161 169 session[:query] = {:project_id => @query.project_id, :filters => @query.filters, :group_by => @query.group_by, :column_names => @query.column_names}
162 170 else
163 171 # retrieve from session
164 172 @query = IssueQuery.find_by_id(session[:query][:id]) if session[:query][:id]
165 173 @query ||= IssueQuery.new(:name => "_", :filters => session[:query][:filters], :group_by => session[:query][:group_by], :column_names => session[:query][:column_names])
166 174 @query.project = @project
167 175 end
168 176 end
169 177
170 178 def retrieve_query_from_session
171 179 if session[:query]
172 180 if session[:query][:id]
173 181 @query = IssueQuery.find_by_id(session[:query][:id])
174 182 return unless @query
175 183 else
176 184 @query = IssueQuery.new(:name => "_", :filters => session[:query][:filters], :group_by => session[:query][:group_by], :column_names => session[:query][:column_names])
177 185 end
178 186 if session[:query].has_key?(:project_id)
179 187 @query.project_id = session[:query][:project_id]
180 188 else
181 189 @query.project = @project
182 190 end
183 191 @query
184 192 end
185 193 end
186 194 end
@@ -1,34 +1,34
1 1 <table class="query-columns">
2 2 <tr>
3 3 <td style="padding-left:0">
4 4 <%= label_tag "available_columns", l(:description_available_columns) %>
5 5 <br />
6 6 <%= select_tag 'available_columns',
7 options_for_select((query.available_inline_columns - query.columns).reject(&:frozen?).collect {|column| [column.caption, column.name]}),
7 options_for_select(query_available_inline_columns_options(query)),
8 8 :multiple => true, :size => 10, :style => "width:150px",
9 9 :ondblclick => "moveOptions(this.form.available_columns, this.form.selected_columns);" %>
10 10 </td>
11 11 <td class="buttons">
12 12 <input type="button" value="&#8594;"
13 13 onclick="moveOptions(this.form.available_columns, this.form.selected_columns);" /><br />
14 14 <input type="button" value="&#8592;"
15 15 onclick="moveOptions(this.form.selected_columns, this.form.available_columns);" />
16 16 </td>
17 17 <td>
18 18 <%= label_tag "selected_columns", l(:description_selected_columns) %>
19 19 <br />
20 20 <%= select_tag((defined?(tag_name) ? tag_name : 'c[]'),
21 options_for_select((query.inline_columns & query.available_inline_columns).reject(&:frozen?).collect {|column| [column.caption, column.name]}),
21 options_for_select(query_selected_inline_columns_options(query)),
22 22 :id => 'selected_columns', :multiple => true, :size => 10, :style => "width:150px",
23 23 :ondblclick => "moveOptions(this.form.selected_columns, this.form.available_columns);") %>
24 24 </td>
25 25 <td class="buttons">
26 26 <input type="button" value="&#8593;" onclick="moveOptionUp(this.form.selected_columns);" /><br />
27 27 <input type="button" value="&#8595;" onclick="moveOptionDown(this.form.selected_columns);" />
28 28 </td>
29 29 </tr>
30 30 </table>
31 31
32 32 <% content_for :header_tags do %>
33 33 <%= javascript_include_tag 'select_list_move' %>
34 34 <% end %>
General Comments 0
You need to be logged in to leave comments. Login now