Redmine 4.1.1

This commit is contained in:
Manuel Cillero 2020-11-22 21:20:06 +01:00
parent 33e7b881a5
commit 3d976f1b3b
1593 changed files with 36180 additions and 19489 deletions

View file

@ -1,7 +1,7 @@
# encoding: utf-8
#
# frozen_string_literal: true
# Redmine - project management software
# Copyright (C) 2006-2017 Jean-Philippe Lang
# Copyright (C) 2006-2019 Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
@ -17,6 +17,8 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
require 'redmine/export/csv'
module QueriesHelper
include ApplicationHelper
@ -28,7 +30,7 @@ module QueriesHelper
group = :label_relations
elsif field_options[:type] == :tree
group = query.is_a?(IssueQuery) ? :label_relations : nil
elsif field =~ /^cf_\d+\./
elsif /^cf_\d+\./.match?(field)
group = (field_options[:through] || field_options[:field]).try(:name)
elsif field =~ /^(.+)\./
# association filters
@ -37,6 +39,8 @@ module QueriesHelper
group = :field_assigned_to
elsif field_options[:type] == :date_past || field_options[:type] == :date
group = :label_date
elsif %w(estimated_hours spent_time).include?(field)
group = :label_time_tracking
end
if group
(grouped[group] ||= []) << [field_options[:name], field]
@ -93,12 +97,13 @@ module QueriesHelper
tags
end
def available_totalable_columns_tags(query)
def available_totalable_columns_tags(query, options={})
tag_name = (options[:name] || 't') + '[]'
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')
tags << content_tag('label', check_box_tag(tag_name, column.name.to_s, query.totalable_columns.include?(column), :id => nil) + " #{column.caption}", :class => 'inline')
end
tags << hidden_field_tag('t[]', '')
tags << hidden_field_tag(tag_name, '')
tags
end
@ -115,6 +120,15 @@ module QueriesHelper
render :partial => 'queries/columns', :locals => {:query => query, :tag_name => tag_name}
end
def available_display_types_tags(query)
tags = ''.html_safe
query.available_display_types.each do |t|
tags << radio_button_tag('display_type', t, @query.display_type == t, :id => "display_type_#{t}") +
content_tag('label', l(:"label_display_type_#{t}"), :for => "display_type_#{t}", :class => "inline")
end
tags
end
def grouped_query_results(items, query, &block)
result_count_by_group = query.result_count_by_group
previous_group, first = false, true
@ -125,7 +139,7 @@ module QueriesHelper
items.each do |item|
group_name = group_count = nil
if query.grouped?
group = query.group_by_column.value(item)
group = query.group_by_column.group_value(item)
if first || group != previous_group
if group.blank? && group != false
group_name = "(#{l(:label_blank_value)})"
@ -152,11 +166,12 @@ module QueriesHelper
def total_tag(column, value)
label = content_tag('span', "#{column.caption}:")
value = if [:hours, :spent_hours, :total_spent_hours, :estimated_hours].include? column.name
format_hours(value)
else
format_object(value)
end
value =
if [:hours, :spent_hours, :total_spent_hours, :estimated_hours].include? column.name
format_hours(value)
else
format_object(value)
end
value = content_tag('span', value, :class => 'value')
content_tag('span', label + " " + value, :class => "total-for-#{column.name.to_s.dasherize}")
end
@ -166,18 +181,16 @@ module QueriesHelper
css, order = nil, column.default_order
if column.name.to_s == query.sort_criteria.first_key
if query.sort_criteria.first_asc?
css = 'sort asc'
css = 'sort asc icon icon-sorted-desc'
order = 'desc'
else
css = 'sort desc'
css = 'sort desc icon icon-sorted-asc'
order = 'asc'
end
end
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
sort_param = {param_key => query.sort_criteria.add(column.name, order).to_param}
sort_param = {$1 => {$2 => sort_param.values.first}} while sort_param.keys.first.to_s =~ /^(.+)\[(.+)\]$/
link_options = {
:title => l(:label_sort_by, "\"#{column.caption}\""),
:class => css
@ -185,14 +198,15 @@ module QueriesHelper
if options[:sort_link_options]
link_options.merge! options[:sort_link_options]
end
content = link_to(column.caption,
content = link_to(
column.caption,
{:params => request.query_parameters.deep_merge(sort_param)},
link_options
)
else
content = column.caption
end
content_tag('th', content)
content_tag('th', content, :class => column.css_classes)
end
def column_content(column, item)
@ -220,7 +234,8 @@ module QueriesHelper
when :done_ratio
progress_bar(value)
when :relations
content_tag('span',
content_tag(
'span',
value.to_s(item) {|other| link_to_issue(other, :subject => false, :tracker => false)}.html_safe,
:class => value.css_classes_for(item))
when :hours, :estimated_hours
@ -258,7 +273,7 @@ module QueriesHelper
value.to_s(object)
when 'Issue'
if object.is_a?(TimeEntry)
"#{value.tracker} ##{value.id}: #{value.subject}"
value.visible? ? "#{value.tracker} ##{value.id}: #{value.subject}" : "##{value.id}"
else
value.id
end
@ -272,7 +287,7 @@ module QueriesHelper
def query_to_csv(items, query, options={})
columns = query.columns
Redmine::Export::CSV.generate do |csv|
Redmine::Export::CSV.generate(:encoding => params[:encoding]) do |csv|
# csv header fields
csv << columns.map {|c| c.caption.to_s}
# csv lines
@ -283,20 +298,20 @@ module QueriesHelper
end
# Retrieve query from session or build a new query
def retrieve_query(klass=IssueQuery, use_session=true)
def retrieve_query(klass=IssueQuery, use_session=true, options={})
session_key = klass.name.underscore.to_sym
if params[:query_id].present?
cond = "project_id IS NULL"
cond << " OR project_id = #{@project.id}" if @project
@query = klass.where(cond).find(params[:query_id])
scope = klass.where(:project_id => nil)
scope = scope.or(klass.where(:project_id => @project)) if @project
@query = scope.find(params[:query_id])
raise ::Unauthorized unless @query.visible?
@query.project = @project
session[session_key] = {:id => @query.id, :project_id => @query.project_id} if use_session
elsif api_request? || params[:set_filter] || !use_session || session[session_key].nil? || session[session_key][:project_id] != (@project ? @project.id : nil)
# Give it a name, required to be valid
@query = klass.new(:name => "_", :project => @project)
@query.build_from_params(params)
@query.build_from_params(params, options[:defaults])
session[session_key] = {:project_id => @query.project_id, :filters => @query.filters, :group_by => @query.group_by, :column_names => @query.column_names, :totalable_names => @query.totalable_names, :sort => @query.sort_criteria.to_a} if use_session
else
# retrieve from session
@ -367,7 +382,7 @@ module QueriesHelper
tags
end
def query_hidden_sort_tag(query)
hidden_field_tag("sort", query.sort_criteria.to_param, :id => nil)
end
@ -381,19 +396,41 @@ module QueriesHelper
def query_links(title, queries)
return '' if queries.empty?
# links to #index on issues/show
url_params = controller_name == 'issues' ? {:controller => 'issues', :action => 'index', :project_id => @project} : {}
url_params =
if controller_name == 'issues'
{:controller => 'issues', :action => 'index', :project_id => @project}
else
{}
end
content_tag('h3', title) + "\n" +
content_tag('ul',
content_tag(
'ul',
queries.collect {|query|
css = 'query'
css << ' selected' if query == @query
content_tag('li', link_to(query.name, url_params.merge(:query_id => query), :class => css))
}.join("\n").html_safe,
css = +'query'
clear_link = +''
if query == @query
css << ' selected'
clear_link += link_to_clear_query
end
content_tag('li',
link_to(query.name,
url_params.merge(:query_id => query),
:class => css) +
clear_link.html_safe)
}.join("\n").html_safe,
:class => 'queries'
) + "\n"
end
def link_to_clear_query
link_to(
l(:button_clear),
{:set_filter => 1, :sort => '', :project_id => @project},
:class => 'icon-only icon-clear-query',
:title => l(:button_clear)
)
end
# Renders the list of queries for the sidebar
def render_sidebar_queries(klass, project)
queries = sidebar_queries(klass, project)