queries_helper.rb
246 lines
| 8.6 KiB
| text/x-ruby
|
RubyLexer
|
r8090 | # encoding: utf-8 | ||
# | ||||
|
r5159 | # Redmine - project management software | ||
|
r13490 | # Copyright (C) 2006-2015 Jean-Philippe Lang | ||
|
r771 | # | ||
# This program is free software; you can redistribute it and/or | ||||
# modify it under the terms of the GNU General Public License | ||||
# as published by the Free Software Foundation; either version 2 | ||||
# of the License, or (at your option) any later version. | ||||
|
r6767 | # | ||
|
r771 | # This program is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
# GNU General Public License for more details. | ||||
|
r6767 | # | ||
|
r771 | # You should have received a copy of the GNU General Public License | ||
# along with this program; if not, write to the Free Software | ||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||||
|
r92 | |||
|
r771 | module QueriesHelper | ||
|
r12779 | include ApplicationHelper | ||
|
r9979 | def filters_options_for_select(query) | ||
|
r13280 | ungrouped = [] | ||
grouped = {} | ||||
query.available_filters.map do |field, field_options| | ||||
|
r13922 | if [:tree, :relation].include?(field_options[:type]) | ||
|
r13280 | group = :label_related_issues | ||
elsif field =~ /^(.+)\./ | ||||
# association filters | ||||
group = "field_#{$1}" | ||||
elsif %w(member_of_group assigned_to_role).include?(field) | ||||
group = :field_assigned_to | ||||
elsif field_options[:type] == :date_past || field_options[:type] == :date | ||||
group = :label_date | ||||
end | ||||
if group | ||||
(grouped[group] ||= []) << [field_options[:name], field] | ||||
else | ||||
ungrouped << [field_options[:name], field] | ||||
end | ||||
end | ||||
# Don't group dates if there's only one (eg. time entries filters) | ||||
if grouped[:label_date].try(:size) == 1 | ||||
ungrouped << grouped.delete(:label_date).first | ||||
end | ||||
s = options_for_select([[]] + ungrouped) | ||||
if grouped.present? | ||||
localized_grouped = grouped.map {|k,v| [l(k), v]} | ||||
s << grouped_options_for_select(localized_grouped) | ||||
|
r9979 | end | ||
|
r13280 | s | ||
|
r92 | end | ||
|
r6767 | |||
|
r11466 | def query_filters_hidden_tags(query) | ||
tags = ''.html_safe | ||||
query.filters.each do |field, options| | ||||
tags << hidden_field_tag("f[]", field, :id => nil) | ||||
tags << hidden_field_tag("op[#{field}]", options[:operator], :id => nil) | ||||
options[:values].each do |value| | ||||
tags << hidden_field_tag("v[#{field}][]", value, :id => nil) | ||||
end | ||||
end | ||||
tags | ||||
end | ||||
def query_columns_hidden_tags(query) | ||||
tags = ''.html_safe | ||||
query.columns.each do |column| | ||||
tags << hidden_field_tag("c[]", column.name, :id => nil) | ||||
end | ||||
tags | ||||
end | ||||
def query_hidden_tags(query) | ||||
query_filters_hidden_tags(query) + query_columns_hidden_tags(query) | ||||
end | ||||
|
r10721 | def available_block_columns_tags(query) | ||
tags = ''.html_safe | ||||
query.available_block_columns.each do |column| | ||||
|
r12378 | tags << content_tag('label', check_box_tag('c[]', column.name.to_s, query.has_column?(column), :id => nil) + " #{column.caption}", :class => 'inline') | ||
|
r10721 | end | ||
tags | ||||
end | ||||
|
r14260 | def available_totalable_columns_tags(query) | ||
tags = ''.html_safe | ||||
query.available_totalable_columns.each do |column| | ||||
tags << content_tag('label', check_box_tag('t[]', column.name.to_s, query.totalable_columns.include?(column), :id => nil) + " #{column.caption}", :class => 'inline') | ||||
end | ||||
tags | ||||
end | ||||
|
r11221 | def query_available_inline_columns_options(query) | ||
(query.available_inline_columns - query.columns).reject(&:frozen?).collect {|column| [column.caption, column.name]} | ||||
end | ||||
def query_selected_inline_columns_options(query) | ||||
(query.inline_columns & query.available_inline_columns).reject(&:frozen?).collect {|column| [column.caption, column.name]} | ||||
end | ||||
|
r11222 | def render_query_columns_selection(query, options={}) | ||
tag_name = (options[:name] || 'c') + '[]' | ||||
render :partial => 'queries/columns', :locals => {:query => query, :tag_name => tag_name} | ||||
end | ||||
|
r14260 | def render_query_totals(query) | ||
return unless query.totalable_columns.present? | ||||
totals = query.totalable_columns.map do |column| | ||||
|
r14283 | total_tag(column, query.total_for(column)) | ||
|
r14260 | end | ||
content_tag('p', totals.join(" ").html_safe, :class => "query-totals") | ||||
end | ||||
|
r14283 | def total_tag(column, value) | ||
label = content_tag('span', "#{column.caption}:") | ||||
value = content_tag('span', format_object(value), :class => 'value') | ||||
content_tag('span', label + " " + value, :class => "total-for-#{column.name.to_s.dasherize}") | ||||
end | ||||
|
r771 | def column_header(column) | ||
|
r2169 | column.sortable ? sort_header_tag(column.name.to_s, :caption => column.caption, | ||
|
r6767 | :default_order => column.default_order) : | ||
|
r6207 | content_tag('th', h(column.caption)) | ||
|
r771 | end | ||
|
r6767 | |||
|
r771 | def column_content(column, issue) | ||
|
r12779 | value = column.value_object(issue) | ||
|
r8601 | if value.is_a?(Array) | ||
|
r10303 | value.collect {|v| column_value(column, issue, v)}.compact.join(', ').html_safe | ||
|
r8601 | else | ||
column_value(column, issue, value) | ||||
end | ||||
end | ||||
def column_value(column, issue, value) | ||||
|
r12087 | case column.name | ||
when :id | ||||
link_to value, issue_path(issue) | ||||
when :subject | ||||
link_to value, issue_path(issue) | ||||
|
r13174 | when :parent | ||
value ? (value.visible? ? link_to_issue(value, :subject => false) : "##{value.id}") : '' | ||||
|
r12087 | when :description | ||
issue.description? ? content_tag('div', textilizable(issue, :description), :class => "wiki") : '' | ||||
when :done_ratio | ||||
|
r14469 | progress_bar(value) | ||
|
r12087 | when :relations | ||
|
r10303 | content_tag('span', | ||
|
r13183 | value.to_s(issue) {|other| link_to_issue(other, :subject => false, :tracker => false)}.html_safe, | ||
|
r10303 | :class => value.css_classes_for(issue)) | ||
|
r2998 | else | ||
|
r12087 | format_object(value) | ||
|
r771 | end | ||
end | ||||
|
r3577 | |||
|
r11211 | def csv_content(column, issue) | ||
|
r12779 | value = column.value_object(issue) | ||
|
r11211 | if value.is_a?(Array) | ||
value.collect {|v| csv_value(column, issue, v)}.compact.join(', ') | ||||
else | ||||
csv_value(column, issue, value) | ||||
end | ||||
end | ||||
|
r13180 | def csv_value(column, object, value) | ||
|
r12779 | format_object(value, false) do |value| | ||
case value.class.name | ||||
when 'Float' | ||||
sprintf("%.2f", value).gsub('.', l(:general_csv_decimal_separator)) | ||||
when 'IssueRelation' | ||||
|
r13183 | value.to_s(object) | ||
|
r13173 | when 'Issue' | ||
|
r13180 | if object.is_a?(TimeEntry) | ||
"#{value.tracker} ##{value.id}: #{value.subject}" | ||||
else | ||||
value.id | ||||
end | ||||
|
r12779 | else | ||
value | ||||
end | ||||
|
r11211 | end | ||
end | ||||
|
r11218 | def query_to_csv(items, query, options={}) | ||
|
r14292 | options ||= {} | ||
|
r11218 | columns = (options[:columns] == 'all' ? query.available_inline_columns : query.inline_columns) | ||
query.available_block_columns.each do |column| | ||||
if options[column.name].present? | ||||
columns << column | ||||
end | ||||
end | ||||
|
r13920 | Redmine::Export::CSV.generate do |csv| | ||
|
r11218 | # csv header fields | ||
|
r13920 | csv << columns.map {|c| c.caption.to_s} | ||
|
r11218 | # csv lines | ||
items.each do |item| | ||||
|
r13920 | csv << columns.map {|c| csv_content(c, item)} | ||
|
r11218 | end | ||
end | ||||
end | ||||
|
r3577 | # Retrieve query from session or build a new query | ||
def retrieve_query | ||||
if !params[:query_id].blank? | ||||
cond = "project_id IS NULL" | ||||
cond << " OR project_id = #{@project.id}" if @project | ||||
|
r11733 | @query = IssueQuery.where(cond).find(params[:query_id]) | ||
|
r6043 | raise ::Unauthorized unless @query.visible? | ||
|
r7536 | @query.project = @project | ||
|
r3577 | session[:query] = {:id => @query.id, :project_id => @query.project_id} | ||
sort_clear | ||||
|
r7529 | elsif api_request? || params[:set_filter] || session[:query].nil? || session[:query][:project_id] != (@project ? @project.id : nil) | ||
# Give it a name, required to be valid | ||||
|
r10737 | @query = IssueQuery.new(:name => "_") | ||
|
r7529 | @query.project = @project | ||
|
r10739 | @query.build_from_params(params) | ||
|
r14260 | session[:query] = {:project_id => @query.project_id, :filters => @query.filters, :group_by => @query.group_by, :column_names => @query.column_names, :totalable_names => @query.totalable_names} | ||
|
r3577 | else | ||
|
r7529 | # retrieve from session | ||
|
r11789 | @query = nil | ||
|
r10737 | @query = IssueQuery.find_by_id(session[:query][:id]) if session[:query][:id] | ||
|
r14260 | @query ||= IssueQuery.new(:name => "_", :filters => session[:query][:filters], :group_by => session[:query][:group_by], :column_names => session[:query][:column_names], :totalable_names => session[:query][:totalable_names]) | ||
|
r7993 | @query.project = @project | ||
|
r7529 | end | ||
end | ||||
|
r7536 | |||
|
r8368 | def retrieve_query_from_session | ||
if session[:query] | ||||
|
r8537 | if session[:query][:id] | ||
|
r10737 | @query = IssueQuery.find_by_id(session[:query][:id]) | ||
|
r8537 | return unless @query | ||
else | ||||
|
r14260 | @query = IssueQuery.new(:name => "_", :filters => session[:query][:filters], :group_by => session[:query][:group_by], :column_names => session[:query][:column_names], :totalable_names => session[:query][:totalable_names]) | ||
|
r8537 | end | ||
|
r8368 | if session[:query].has_key?(:project_id) | ||
@query.project_id = session[:query][:project_id] | ||||
else | ||||
@query.project = @project | ||||
end | ||||
@query | ||||
end | ||||
end | ||||
|
r92 | end | ||