Redmine 4.1.1
This commit is contained in:
parent
33e7b881a5
commit
3d976f1b3b
1593 changed files with 36180 additions and 19489 deletions
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue