Revision 1298:4f746d8966dd app/helpers
| app/helpers/account_helper.rb | ||
|---|---|---|
| 1 | 1 |
# encoding: utf-8 |
| 2 | 2 |
# |
| 3 | 3 |
# Redmine - project management software |
| 4 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 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 |
| app/helpers/activities_helper.rb | ||
|---|---|---|
| 1 |
# encoding: utf-8 |
|
| 2 |
# |
|
| 3 |
# Redmine - project management software |
|
| 4 |
# Copyright (C) 2006-2013 Jean-Philippe Lang |
|
| 5 |
# |
|
| 6 |
# This program is free software; you can redistribute it and/or |
|
| 7 |
# modify it under the terms of the GNU General Public License |
|
| 8 |
# as published by the Free Software Foundation; either version 2 |
|
| 9 |
# of the License, or (at your option) any later version. |
|
| 10 |
# |
|
| 11 |
# This program is distributed in the hope that it will be useful, |
|
| 12 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 13 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 14 |
# GNU General Public License for more details. |
|
| 15 |
# |
|
| 16 |
# You should have received a copy of the GNU General Public License |
|
| 17 |
# along with this program; if not, write to the Free Software |
|
| 18 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
| 1 | 19 |
|
| 2 | 20 |
module ActivitiesHelper |
| 3 | 21 |
|
| ... | ... | |
| 147 | 165 |
threshold = insthash.values.sort.last(count).first |
| 148 | 166 |
insthash.keys.select { |k| insthash[k] >= threshold }.sample(count)
|
| 149 | 167 |
end |
| 168 |
|
|
| 169 |
def sort_activity_events(events) |
|
| 170 |
events_by_group = events.group_by(&:event_group) |
|
| 171 |
sorted_events = [] |
|
| 172 |
events.sort {|x, y| y.event_datetime <=> x.event_datetime}.each do |event|
|
|
| 173 |
if group_events = events_by_group.delete(event.event_group) |
|
| 174 |
group_events.sort {|x, y| y.event_datetime <=> x.event_datetime}.each_with_index do |e, i|
|
|
| 175 |
sorted_events << [e, i > 0] |
|
| 176 |
end |
|
| 177 |
end |
|
| 178 |
end |
|
| 179 |
sorted_events |
|
| 180 |
end |
|
| 150 | 181 |
|
| 151 | 182 |
end |
| app/helpers/admin_helper.rb | ||
|---|---|---|
| 1 | 1 |
# encoding: utf-8 |
| 2 | 2 |
# |
| 3 | 3 |
# Redmine - project management software |
| 4 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 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 |
| app/helpers/application_helper.rb | ||
|---|---|---|
| 1 | 1 |
# encoding: utf-8 |
| 2 | 2 |
# |
| 3 | 3 |
# Redmine - project management software |
| 4 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 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 |
| ... | ... | |
| 24 | 24 |
include Redmine::WikiFormatting::Macros::Definitions |
| 25 | 25 |
include Redmine::I18n |
| 26 | 26 |
include GravatarHelper::PublicMethods |
| 27 |
include Redmine::Pagination::Helper |
|
| 27 | 28 |
|
| 28 | 29 |
extend Forwardable |
| 29 | 30 |
def_delegators :wiki_helper, :wikitoolbar_for, :heads_for_wiki_formatter |
| ... | ... | |
| 90 | 91 |
# * :download - Force download (default: false) |
| 91 | 92 |
def link_to_attachment(attachment, options={})
|
| 92 | 93 |
text = options.delete(:text) || attachment.filename |
| 93 |
action = options.delete(:download) ? 'download' : 'show' |
|
| 94 |
opt_only_path = {}
|
|
| 95 |
opt_only_path[:only_path] = (options[:only_path] == false ? false : true) |
|
| 96 |
options.delete(:only_path) |
|
| 97 |
link_to(h(text), |
|
| 98 |
{:controller => 'attachments', :action => action,
|
|
| 99 |
:id => attachment, :filename => attachment.filename}.merge(opt_only_path), |
|
| 100 |
options) |
|
| 94 |
route_method = options.delete(:download) ? :download_named_attachment_path : :named_attachment_path |
|
| 95 |
html_options = options.slice!(:only_path) |
|
| 96 |
url = send(route_method, attachment, attachment.filename, options) |
|
| 97 |
link_to text, url, html_options |
|
| 101 | 98 |
end |
| 102 | 99 |
|
| 103 | 100 |
# Generates a link to a SCM revision |
| ... | ... | |
| 119 | 116 |
# Generates a link to a message |
| 120 | 117 |
def link_to_message(message, options={}, html_options = nil)
|
| 121 | 118 |
link_to( |
| 122 |
h(truncate(message.subject, :length => 60)), |
|
| 123 |
{ :controller => 'messages', :action => 'show',
|
|
| 124 |
:board_id => message.board_id, |
|
| 125 |
:id => (message.parent_id || message.id), |
|
| 119 |
truncate(message.subject, :length => 60), |
|
| 120 |
board_message_path(message.board_id, message.parent_id || message.id, {
|
|
| 126 | 121 |
:r => (message.parent_id && message.id), |
| 127 | 122 |
:anchor => (message.parent_id ? "message-#{message.id}" : nil)
|
| 128 |
}.merge(options), |
|
| 123 |
}.merge(options)),
|
|
| 129 | 124 |
html_options |
| 130 | 125 |
) |
| 131 | 126 |
end |
| ... | ... | |
| 134 | 129 |
# Examples: |
| 135 | 130 |
# |
| 136 | 131 |
# link_to_project(project) # => link to the specified project overview |
| 137 |
# link_to_project(project, :action=>'settings') # => link to project settings |
|
| 138 | 132 |
# link_to_project(project, {:only_path => false}, :class => "project") # => 3rd arg adds html options
|
| 139 | 133 |
# link_to_project(project, {}, :class => "project") # => html options with default url (project overview)
|
| 140 | 134 |
# |
| 141 | 135 |
def link_to_project(project, options={}, html_options = nil)
|
| 142 | 136 |
if project.archived? |
| 143 |
h(project) |
|
| 137 |
h(project.name) |
|
| 138 |
elsif options.key?(:action) |
|
| 139 |
ActiveSupport::Deprecation.warn "#link_to_project with :action option is deprecated and will be removed in Redmine 3.0." |
|
| 140 |
url = {:controller => 'projects', :action => 'show', :id => project}.merge(options)
|
|
| 141 |
link_to project.name, url, html_options |
|
| 144 | 142 |
else |
| 145 |
url = {:controller => 'projects', :action => 'show', :id => project}.merge(options)
|
|
| 146 |
link_to(h(project), url, html_options) |
|
| 143 |
link_to project.name, project_path(project, options), html_options |
|
| 144 |
end |
|
| 145 |
end |
|
| 146 |
|
|
| 147 |
# Generates a link to a project settings if active |
|
| 148 |
def link_to_project_settings(project, options={}, html_options=nil)
|
|
| 149 |
if project.active? |
|
| 150 |
link_to project.name, settings_project_path(project, options), html_options |
|
| 151 |
elsif project.archived? |
|
| 152 |
h(project.name) |
|
| 153 |
else |
|
| 154 |
link_to project.name, project_path(project, options), html_options |
|
| 147 | 155 |
end |
| 148 | 156 |
end |
| 149 | 157 |
|
| ... | ... | |
| 152 | 160 |
end |
| 153 | 161 |
|
| 154 | 162 |
def thumbnail_tag(attachment) |
| 155 |
link_to image_tag(url_for(:controller => 'attachments', :action => 'thumbnail', :id => attachment)),
|
|
| 156 |
{:controller => 'attachments', :action => 'show', :id => attachment, :filename => attachment.filename},
|
|
| 163 |
link_to image_tag(thumbnail_path(attachment)),
|
|
| 164 |
named_attachment_path(attachment, attachment.filename),
|
|
| 157 | 165 |
:title => attachment.filename |
| 158 | 166 |
end |
| 159 | 167 |
|
| ... | ... | |
| 187 | 195 |
|
| 188 | 196 |
def format_version_name(version) |
| 189 | 197 |
if version.project == @project |
| 190 |
h(version)
|
|
| 198 |
h(version)
|
|
| 191 | 199 |
else |
| 192 | 200 |
h("#{version.project} - #{version}")
|
| 193 | 201 |
end |
| ... | ... | |
| 341 | 349 |
def options_for_membership_project_select(principal, projects) |
| 342 | 350 |
options = content_tag('option', "--- #{l(:actionview_instancetag_blank_option)} ---")
|
| 343 | 351 |
options << project_tree_options_for_select(projects) do |p| |
| 344 |
{:disabled => principal.projects.include?(p)}
|
|
| 352 |
{:disabled => principal.projects.to_a.include?(p)}
|
|
| 345 | 353 |
end |
| 346 | 354 |
options |
| 347 | 355 |
end |
| ... | ... | |
| 397 | 405 |
str.blank? ? nil : str |
| 398 | 406 |
end |
| 399 | 407 |
|
| 400 |
def pagination_links_full(paginator, count=nil, options={})
|
|
| 401 |
page_param = options.delete(:page_param) || :page |
|
| 402 |
per_page_links = options.delete(:per_page_links) |
|
| 403 |
url_param = params.dup |
|
| 404 |
|
|
| 405 |
html = '' |
|
| 406 |
if paginator.current.previous |
|
| 407 |
# \xc2\xab(utf-8) = « |
|
| 408 |
html << link_to_content_update( |
|
| 409 |
"\xc2\xab " + l(:label_previous), |
|
| 410 |
url_param.merge(page_param => paginator.current.previous)) + ' ' |
|
| 411 |
end |
|
| 412 |
|
|
| 413 |
html << (pagination_links_each(paginator, options) do |n| |
|
| 414 |
link_to_content_update(n.to_s, url_param.merge(page_param => n)) |
|
| 415 |
end || '') |
|
| 416 |
|
|
| 417 |
if paginator.current.next |
|
| 418 |
# \xc2\xbb(utf-8) = » |
|
| 419 |
html << ' ' + link_to_content_update( |
|
| 420 |
(l(:label_next) + " \xc2\xbb"), |
|
| 421 |
url_param.merge(page_param => paginator.current.next)) |
|
| 422 |
end |
|
| 423 |
|
|
| 424 |
unless count.nil? |
|
| 425 |
html << " (#{paginator.current.first_item}-#{paginator.current.last_item}/#{count})"
|
|
| 426 |
if per_page_links != false && links = per_page_links(paginator.items_per_page, count) |
|
| 427 |
html << " | #{links}"
|
|
| 428 |
end |
|
| 429 |
end |
|
| 430 |
|
|
| 431 |
html.html_safe |
|
| 432 |
end |
|
| 433 |
|
|
| 434 |
def per_page_links(selected=nil, item_count=nil) |
|
| 435 |
values = Setting.per_page_options_array |
|
| 436 |
if item_count && values.any? |
|
| 437 |
if item_count > values.first |
|
| 438 |
max = values.detect {|value| value >= item_count} || item_count
|
|
| 439 |
else |
|
| 440 |
max = item_count |
|
| 441 |
end |
|
| 442 |
values = values.select {|value| value <= max || value == selected}
|
|
| 443 |
end |
|
| 444 |
if values.empty? || (values.size == 1 && values.first == selected) |
|
| 445 |
return nil |
|
| 446 |
end |
|
| 447 |
links = values.collect do |n| |
|
| 448 |
n == selected ? n : link_to_content_update(n, params.merge(:per_page => n)) |
|
| 449 |
end |
|
| 450 |
l(:label_display_per_page, links.join(', '))
|
|
| 451 |
end |
|
| 452 |
|
|
| 453 | 408 |
def reorder_links(name, url, method = :post) |
| 454 | 409 |
link_to(image_tag('2uparrow.png', :alt => l(:label_sort_highest)),
|
| 455 | 410 |
url.merge({"#{name}[move_to]" => 'highest'}),
|
| ... | ... | |
| 529 | 484 |
end |
| 530 | 485 |
|
| 531 | 486 |
def accesskey(s) |
| 532 |
Redmine::AccessKeys.key_for s |
|
| 487 |
@used_accesskeys ||= [] |
|
| 488 |
key = Redmine::AccessKeys.key_for(s) |
|
| 489 |
return nil if @used_accesskeys.include?(key) |
|
| 490 |
@used_accesskeys << key |
|
| 491 |
key |
|
| 533 | 492 |
end |
| 534 | 493 |
|
| 535 | 494 |
# Formats text according to system settings. |
| ... | ... | |
| 617 | 576 |
filename, ext, alt, alttext = $1.downcase, $2, $3, $4 |
| 618 | 577 |
# search for the picture in attachments |
| 619 | 578 |
if found = Attachment.latest_attach(attachments, filename) |
| 620 |
image_url = url_for :only_path => only_path, :controller => 'attachments', |
|
| 621 |
:action => 'download', :id => found |
|
| 579 |
image_url = download_named_attachment_path(found, found.filename, :only_path => only_path) |
|
| 622 | 580 |
desc = found.description.to_s.gsub('"', '')
|
| 623 | 581 |
if !desc.blank? && alttext.blank? |
| 624 | 582 |
alt = " title=\"#{desc}\" alt=\"#{desc}\""
|
| ... | ... | |
| 647 | 605 |
esc, all, page, title = $1, $2, $3, $5 |
| 648 | 606 |
if esc.nil? |
| 649 | 607 |
if page =~ /^([^\:]+)\:(.*)$/ |
| 650 |
link_project = Project.find_by_identifier($1) || Project.find_by_name($1)
|
|
| 651 |
page = $2
|
|
| 652 |
title ||= $1 if page.blank?
|
|
| 608 |
identifier, page = $1, $2
|
|
| 609 |
link_project = Project.find_by_identifier(identifier) || Project.find_by_name(identifier)
|
|
| 610 |
title ||= identifier if page.blank?
|
|
| 653 | 611 |
end |
| 654 | 612 |
|
| 655 | 613 |
if link_project && link_project.wiki |
| ... | ... | |
| 814 | 772 |
repository = project.repository |
| 815 | 773 |
end |
| 816 | 774 |
if prefix == 'commit' |
| 817 |
if repository && (changeset = Changeset.visible.find(:first, :conditions => ["repository_id = ? AND scmid LIKE ?", repository.id, "#{name}%"]))
|
|
| 775 |
if repository && (changeset = Changeset.visible.where("repository_id = ? AND scmid LIKE ?", repository.id, "#{name}%").first)
|
|
| 818 | 776 |
link = link_to h("#{project_prefix}#{repo_prefix}#{name}"), {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :repository_id => repository.identifier_param, :rev => changeset.identifier},
|
| 819 | 777 |
:class => 'changeset', |
| 820 |
:title => truncate_single_line(h(changeset.comments), :length => 100)
|
|
| 778 |
:title => truncate_single_line(changeset.comments, :length => 100)
|
|
| 821 | 779 |
end |
| 822 | 780 |
else |
| 823 | 781 |
if repository && User.current.allowed_to?(:browse_repository, project) |
| 824 |
name =~ %r{^[/\\]*(.*?)(@([0-9a-f]+))?(#(L\d+))?$}
|
|
| 782 |
name =~ %r{^[/\\]*(.*?)(@([^/\\@]+?))?(#(L\d+))?$}
|
|
| 825 | 783 |
path, rev, anchor = $1, $3, $5 |
| 826 | 784 |
link = link_to h("#{project_prefix}#{prefix}:#{repo_prefix}#{name}"), {:controller => 'repositories', :action => (prefix == 'export' ? 'raw' : 'entry'), :id => project, :repository_id => repository.identifier_param,
|
| 827 | 785 |
:path => to_path_param(path), |
| ... | ... | |
| 835 | 793 |
when 'attachment' |
| 836 | 794 |
attachments = options[:attachments] || (obj && obj.respond_to?(:attachments) ? obj.attachments : nil) |
| 837 | 795 |
if attachments && attachment = Attachment.latest_attach(attachments, name) |
| 838 |
link = link_to h(attachment.filename), {:only_path => only_path, :controller => 'attachments', :action => 'download', :id => attachment},
|
|
| 839 |
:class => 'attachment' |
|
| 796 |
link = link_to_attachment(attachment, :only_path => only_path, :download => true, :class => 'attachment') |
|
| 840 | 797 |
end |
| 841 | 798 |
when 'project' |
| 842 |
if p = Project.visible.find(:first, :conditions => ["identifier = :s OR LOWER(name) = :s", {:s => name.downcase}])
|
|
| 799 |
if p = Project.visible.where("identifier = :s OR LOWER(name) = :s", :s => name.downcase).first
|
|
| 843 | 800 |
link = link_to_project(p, {:only_path => only_path}, :class => 'project')
|
| 844 | 801 |
end |
| 845 | 802 |
end |
| ... | ... | |
| 1092 | 1049 |
(pcts[1] > 0 ? content_tag('td', '', :style => "width: #{pcts[1]}%;", :class => 'done') : ''.html_safe) +
|
| 1093 | 1050 |
(pcts[2] > 0 ? content_tag('td', '', :style => "width: #{pcts[2]}%;", :class => 'todo') : ''.html_safe)
|
| 1094 | 1051 |
), :class => 'progress', :style => "width: #{width};").html_safe +
|
| 1095 |
content_tag('p', legend, :class => 'pourcent').html_safe
|
|
| 1052 |
content_tag('p', legend, :class => 'percent').html_safe
|
|
| 1096 | 1053 |
end |
| 1097 | 1054 |
|
| 1098 | 1055 |
def checked_image(checked=true) |
| ... | ... | |
| 1136 | 1093 |
"var datepickerOptions={dateFormat: 'yy-mm-dd', firstDay: #{start_of_week}, " +
|
| 1137 | 1094 |
"showOn: 'button', buttonImageOnly: true, buttonImage: '" + |
| 1138 | 1095 |
path_to_image('/images/calendar.png') +
|
| 1139 |
"', showButtonPanel: true};") |
|
| 1096 |
"', showButtonPanel: true, showWeek: true, showOtherMonths: true, selectOtherMonths: true};")
|
|
| 1140 | 1097 |
jquery_locale = l('jquery.locale', :default => current_language.to_s)
|
| 1141 | 1098 |
unless jquery_locale == 'en' |
| 1142 | 1099 |
tags << javascript_include_tag("i18n/jquery.ui.datepicker-#{jquery_locale}.js")
|
| ... | ... | |
| 1240 | 1197 |
|
| 1241 | 1198 |
def sanitize_anchor_name(anchor) |
| 1242 | 1199 |
if ''.respond_to?(:encoding) || RUBY_PLATFORM == 'java' |
| 1243 |
anchor.gsub(%r{[^\p{Word}\s\-]}, '').gsub(%r{\s+(\-+\s*)?}, '-')
|
|
| 1200 |
anchor.gsub(%r{[^\s\-\p{Word}]}, '').gsub(%r{\s+(\-+\s*)?}, '-')
|
|
| 1244 | 1201 |
else |
| 1245 | 1202 |
# TODO: remove when ruby1.8 is no longer supported |
| 1246 | 1203 |
anchor.gsub(%r{[^\w\s\-]}, '').gsub(%r{\s+(\-+\s*)?}, '-')
|
| ... | ... | |
| 1249 | 1206 |
|
| 1250 | 1207 |
# Returns the javascript tags that are included in the html layout head |
| 1251 | 1208 |
def javascript_heads |
| 1252 |
tags = javascript_include_tag('jquery-1.7.2-ui-1.8.21-ujs-2.0.3', 'application')
|
|
| 1209 |
tags = javascript_include_tag('jquery-1.8.3-ui-1.9.2-ujs-2.0.3', 'application')
|
|
| 1253 | 1210 |
unless User.current.pref.warn_on_leaving_unsaved == '0' |
| 1254 | 1211 |
tags << "\n".html_safe + javascript_tag("$(window).load(function(){ warnLeavingUnsaved('#{escape_javascript l(:text_warn_on_leaving_unsaved)}'); });")
|
| 1255 | 1212 |
end |
| app/helpers/attachments_helper.rb | ||
|---|---|---|
| 1 | 1 |
# encoding: utf-8 |
| 2 | 2 |
# |
| 3 | 3 |
# Redmine - project management software |
| 4 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 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 |
| app/helpers/auth_sources_helper.rb | ||
|---|---|---|
| 1 | 1 |
# encoding: utf-8 |
| 2 | 2 |
# |
| 3 | 3 |
# Redmine - project management software |
| 4 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 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 |
| app/helpers/boards_helper.rb | ||
|---|---|---|
| 1 | 1 |
# encoding: utf-8 |
| 2 | 2 |
# |
| 3 | 3 |
# Redmine - project management software |
| 4 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 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 |
| app/helpers/calendars_helper.rb | ||
|---|---|---|
| 1 | 1 |
# encoding: utf-8 |
| 2 | 2 |
# |
| 3 | 3 |
# Redmine - project management software |
| 4 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 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 |
| app/helpers/context_menus_helper.rb | ||
|---|---|---|
| 1 | 1 |
# encoding: utf-8 |
| 2 | 2 |
# |
| 3 | 3 |
# Redmine - project management software |
| 4 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 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 |
| ... | ... | |
| 36 | 36 |
|
| 37 | 37 |
def bulk_update_custom_field_context_menu_link(field, text, value) |
| 38 | 38 |
context_menu_link h(text), |
| 39 |
{:controller => 'issues', :action => 'bulk_update', :ids => @issue_ids, :issue => {'custom_field_values' => {field.id => value}}, :back_url => @back},
|
|
| 39 |
bulk_update_issues_path(:ids => @issue_ids, :issue => {'custom_field_values' => {field.id => value}}, :back_url => @back),
|
|
| 40 | 40 |
:method => :post, |
| 41 | 41 |
:selected => (@issue && @issue.custom_field_value(field) == value) |
| 42 | 42 |
end |
| app/helpers/custom_fields_helper.rb | ||
|---|---|---|
| 1 | 1 |
# encoding: utf-8 |
| 2 | 2 |
# |
| 3 | 3 |
# Redmine - project management software |
| 4 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 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 |
| ... | ... | |
| 24 | 24 |
end |
| 25 | 25 |
|
| 26 | 26 |
# Return custom field html tag corresponding to its format |
| 27 |
def custom_field_tag(name, custom_value)
|
|
| 27 |
def custom_field_tag(name, custom_value) |
|
| 28 | 28 |
custom_field = custom_value.custom_field |
| 29 | 29 |
field_name = "#{name}[custom_field_values][#{custom_field.id}]"
|
| 30 | 30 |
field_name << "[]" if custom_field.multiple? |
| app/helpers/documents_helper.rb | ||
|---|---|---|
| 1 | 1 |
# encoding: utf-8 |
| 2 | 2 |
# |
| 3 | 3 |
# Redmine - project management software |
| 4 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 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 |
| app/helpers/enumerations_helper.rb | ||
|---|---|---|
| 1 | 1 |
# encoding: utf-8 |
| 2 | 2 |
# |
| 3 | 3 |
# Redmine - project management software |
| 4 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 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 |
| app/helpers/gantt_helper.rb | ||
|---|---|---|
| 1 | 1 |
# encoding: utf-8 |
| 2 | 2 |
# |
| 3 | 3 |
# Redmine - project management software |
| 4 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 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 |
| ... | ... | |
| 24 | 24 |
when :in |
| 25 | 25 |
if gantt.zoom < 4 |
| 26 | 26 |
link_to_content_update l(:text_zoom_in), |
| 27 |
params.merge(gantt.params.merge(:zoom => (gantt.zoom+1))),
|
|
| 27 |
params.merge(gantt.params.merge(:zoom => (gantt.zoom + 1))),
|
|
| 28 | 28 |
:class => 'icon icon-zoom-in' |
| 29 | 29 |
else |
| 30 |
content_tag('span', l(:text_zoom_in), :class => 'icon icon-zoom-in').html_safe
|
|
| 30 |
content_tag(:span, l(:text_zoom_in), :class => 'icon icon-zoom-in').html_safe
|
|
| 31 | 31 |
end |
| 32 | 32 |
|
| 33 | 33 |
when :out |
| 34 | 34 |
if gantt.zoom > 1 |
| 35 | 35 |
link_to_content_update l(:text_zoom_out), |
| 36 |
params.merge(gantt.params.merge(:zoom => (gantt.zoom-1))),
|
|
| 36 |
params.merge(gantt.params.merge(:zoom => (gantt.zoom - 1))),
|
|
| 37 | 37 |
:class => 'icon icon-zoom-out' |
| 38 | 38 |
else |
| 39 |
content_tag('span', l(:text_zoom_out), :class => 'icon icon-zoom-out').html_safe
|
|
| 39 |
content_tag(:span, l(:text_zoom_out), :class => 'icon icon-zoom-out').html_safe
|
|
| 40 | 40 |
end |
| 41 | 41 |
end |
| 42 | 42 |
end |
| app/helpers/groups_helper.rb | ||
|---|---|---|
| 1 | 1 |
# encoding: utf-8 |
| 2 | 2 |
# |
| 3 | 3 |
# Redmine - project management software |
| 4 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 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 |
| ... | ... | |
| 24 | 24 |
{:name => 'memberships', :partial => 'groups/memberships', :label => :label_project_plural}
|
| 25 | 25 |
] |
| 26 | 26 |
end |
| 27 |
|
|
| 28 |
def render_principals_for_new_group_users(group) |
|
| 29 |
scope = User.active.sorted.not_in_group(group).like(params[:q]) |
|
| 30 |
principal_count = scope.count |
|
| 31 |
principal_pages = Redmine::Pagination::Paginator.new principal_count, 100, params['page'] |
|
| 32 |
principals = scope.offset(principal_pages.offset).limit(principal_pages.per_page).all |
|
| 33 |
|
|
| 34 |
s = content_tag('div', principals_check_box_tags('user_ids[]', principals), :id => 'principals')
|
|
| 35 |
|
|
| 36 |
links = pagination_links_full(principal_pages, principal_count, :per_page_links => false) {|text, parameters, options|
|
|
| 37 |
link_to text, autocomplete_for_user_group_path(group, parameters.merge(:q => params[:q], :format => 'js')), :remote => true |
|
| 38 |
} |
|
| 39 |
|
|
| 40 |
s + content_tag('p', links, :class => 'pagination')
|
|
| 41 |
end |
|
| 27 | 42 |
end |
| app/helpers/issue_categories_helper.rb | ||
|---|---|---|
| 1 | 1 |
# encoding: utf-8 |
| 2 | 2 |
# |
| 3 | 3 |
# Redmine - project management software |
| 4 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 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 |
| app/helpers/issue_relations_helper.rb | ||
|---|---|---|
| 1 | 1 |
# encoding: utf-8 |
| 2 | 2 |
# |
| 3 | 3 |
# Redmine - project management software |
| 4 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 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 |
| app/helpers/issue_statuses_helper.rb | ||
|---|---|---|
| 1 | 1 |
# encoding: utf-8 |
| 2 | 2 |
# |
| 3 | 3 |
# Redmine - project management software |
| 4 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 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 |
| app/helpers/issues_helper.rb | ||
|---|---|---|
| 1 | 1 |
# encoding: utf-8 |
| 2 | 2 |
# |
| 3 | 3 |
# Redmine - project management software |
| 4 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 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 |
| ... | ... | |
| 184 | 184 |
|
| 185 | 185 |
def sidebar_queries |
| 186 | 186 |
unless @sidebar_queries |
| 187 |
@sidebar_queries = Query.visible.all( |
|
| 187 |
@sidebar_queries = IssueQuery.visible.all(
|
|
| 188 | 188 |
:order => "#{Query.table_name}.name ASC",
|
| 189 | 189 |
# Project specific queries and global queries |
| 190 | 190 |
:conditions => (@project.nil? ? ["project_id IS NULL"] : ["project_id IS NULL OR project_id = ?", @project.id]) |
| ... | ... | |
| 347 | 347 |
|
| 348 | 348 |
# Find the name of an associated record stored in the field attribute |
| 349 | 349 |
def find_name_by_reflection(field, id) |
| 350 |
unless id.present? |
|
| 351 |
return nil |
|
| 352 |
end |
|
| 350 | 353 |
association = Issue.reflect_on_association(field.to_sym) |
| 351 | 354 |
if association |
| 352 | 355 |
record = association.class_name.constantize.find_by_id(id) |
| ... | ... | |
| 370 | 373 |
end |
| 371 | 374 |
end |
| 372 | 375 |
end |
| 373 |
|
|
| 374 |
def issues_to_csv(issues, project, query, options={})
|
|
| 375 |
decimal_separator = l(:general_csv_decimal_separator) |
|
| 376 |
encoding = l(:general_csv_encoding) |
|
| 377 |
columns = (options[:columns] == 'all' ? query.available_inline_columns : query.inline_columns) |
|
| 378 |
if options[:description] |
|
| 379 |
if description = query.available_columns.detect {|q| q.name == :description}
|
|
| 380 |
columns << description |
|
| 381 |
end |
|
| 382 |
end |
|
| 383 |
|
|
| 384 |
export = FCSV.generate(:col_sep => l(:general_csv_separator)) do |csv| |
|
| 385 |
# csv header fields |
|
| 386 |
csv << [ "#" ] + columns.collect {|c| Redmine::CodesetUtil.from_utf8(c.caption.to_s, encoding) }
|
|
| 387 |
|
|
| 388 |
# csv lines |
|
| 389 |
issues.each do |issue| |
|
| 390 |
col_values = columns.collect do |column| |
|
| 391 |
s = if column.is_a?(QueryCustomFieldColumn) |
|
| 392 |
cv = issue.custom_field_values.detect {|v| v.custom_field_id == column.custom_field.id}
|
|
| 393 |
show_value(cv) |
|
| 394 |
else |
|
| 395 |
value = column.value(issue) |
|
| 396 |
if value.is_a?(Date) |
|
| 397 |
format_date(value) |
|
| 398 |
elsif value.is_a?(Time) |
|
| 399 |
format_time(value) |
|
| 400 |
elsif value.is_a?(Float) |
|
| 401 |
("%.2f" % value).gsub('.', decimal_separator)
|
|
| 402 |
else |
|
| 403 |
value |
|
| 404 |
end |
|
| 405 |
end |
|
| 406 |
s.to_s |
|
| 407 |
end |
|
| 408 |
csv << [ issue.id.to_s ] + col_values.collect {|c| Redmine::CodesetUtil.from_utf8(c.to_s, encoding) }
|
|
| 409 |
end |
|
| 410 |
end |
|
| 411 |
export |
|
| 412 |
end |
|
| 413 | 376 |
end |
| app/helpers/journals_helper.rb | ||
|---|---|---|
| 1 | 1 |
# encoding: utf-8 |
| 2 | 2 |
# |
| 3 | 3 |
# Redmine - project management software |
| 4 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 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 |
| app/helpers/mail_handler_helper.rb | ||
|---|---|---|
| 1 | 1 |
# encoding: utf-8 |
| 2 | 2 |
# |
| 3 | 3 |
# Redmine - project management software |
| 4 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 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 |
| app/helpers/members_helper.rb | ||
|---|---|---|
| 1 | 1 |
# encoding: utf-8 |
| 2 | 2 |
# |
| 3 | 3 |
# Redmine - project management software |
| 4 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 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 |
| ... | ... | |
| 18 | 18 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| 19 | 19 |
|
| 20 | 20 |
module MembersHelper |
| 21 |
def render_principals_for_new_members(project) |
|
| 22 |
scope = Principal.active.sorted.not_member_of(project).like(params[:q]) |
|
| 23 |
principal_count = scope.count |
|
| 24 |
principal_pages = Redmine::Pagination::Paginator.new principal_count, 100, params['page'] |
|
| 25 |
principals = scope.offset(principal_pages.offset).limit(principal_pages.per_page).all |
|
| 26 |
|
|
| 27 |
s = content_tag('div', principals_check_box_tags('membership[user_ids][]', principals), :id => 'principals')
|
|
| 28 |
|
|
| 29 |
links = pagination_links_full(principal_pages, principal_count, :per_page_links => false) {|text, parameters, options|
|
|
| 30 |
link_to text, autocomplete_project_memberships_path(project, parameters.merge(:q => params[:q], :format => 'js')), :remote => true |
|
| 31 |
} |
|
| 32 |
|
|
| 33 |
s + content_tag('p', links, :class => 'pagination')
|
|
| 34 |
end |
|
| 21 | 35 |
end |
| app/helpers/messages_helper.rb | ||
|---|---|---|
| 1 | 1 |
# encoding: utf-8 |
| 2 | 2 |
# |
| 3 | 3 |
# Redmine - project management software |
| 4 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 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 |
| app/helpers/my_helper.rb | ||
|---|---|---|
| 1 | 1 |
# encoding: utf-8 |
| 2 | 2 |
# |
| 3 | 3 |
# Redmine - project management software |
| 4 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 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 |
| ... | ... | |
| 25 | 25 |
user.projects.select { |p| p.visible? }.map { |p| p.members.map { |m| m.user_id } }.flatten.sort.uniq.reject { |i| user.id == i }
|
| 26 | 26 |
end |
| 27 | 27 |
|
| 28 |
def calendar_items(startdt, enddt) |
|
| 29 |
Issue.visible. |
|
| 30 |
where(:project_id => User.current.projects.map(&:id)). |
|
| 31 |
where("(start_date>=? and start_date<=?) or (due_date>=? and due_date<=?)", startdt, enddt, startdt, enddt).
|
|
| 32 |
includes(:project, :tracker, :priority, :assigned_to). |
|
| 33 |
all |
|
| 34 |
end |
|
| 35 |
|
|
| 36 |
def documents_items |
|
| 37 |
Document.visible.order("#{Document.table_name}.created_on DESC").limit(10).all
|
|
| 38 |
end |
|
| 39 |
|
|
| 40 |
def issuesassignedtome_items |
|
| 41 |
Issue.visible.open. |
|
| 42 |
where(:assigned_to_id => ([User.current.id] + User.current.group_ids)). |
|
| 43 |
limit(10). |
|
| 44 |
includes(:status, :project, :tracker, :priority). |
|
| 45 |
order("#{IssuePriority.table_name}.position DESC, #{Issue.table_name}.updated_on DESC").
|
|
| 46 |
all |
|
| 47 |
end |
|
| 48 |
|
|
| 49 |
def issuesreportedbyme_items |
|
| 50 |
Issue.visible. |
|
| 51 |
where(:author_id => User.current.id). |
|
| 52 |
limit(10). |
|
| 53 |
includes(:status, :project, :tracker). |
|
| 54 |
order("#{Issue.table_name}.updated_on DESC").
|
|
| 55 |
all |
|
| 56 |
end |
|
| 57 |
|
|
| 58 |
def issueswatched_items |
|
| 59 |
Issue.visible.on_active_project.watched_by(User.current.id).recently_updated.limit(10).all |
|
| 60 |
end |
|
| 61 |
|
|
| 62 |
def news_items |
|
| 63 |
News.visible. |
|
| 64 |
where(:project_id => User.current.projects.map(&:id)). |
|
| 65 |
limit(10). |
|
| 66 |
includes(:project, :author). |
|
| 67 |
order("#{News.table_name}.created_on DESC").
|
|
| 68 |
all |
|
| 69 |
end |
|
| 70 |
|
|
| 71 |
def timelog_items |
|
| 72 |
TimeEntry. |
|
| 73 |
where("#{TimeEntry.table_name}.user_id = ? AND #{TimeEntry.table_name}.spent_on BETWEEN ? AND ?", User.current.id, Date.today - 6, Date.today).
|
|
| 74 |
includes(:activity, :project, {:issue => [:tracker, :status]}).
|
|
| 75 |
order("#{TimeEntry.table_name}.spent_on DESC, #{Project.table_name}.name ASC, #{Tracker.table_name}.position ASC, #{Issue.table_name}.id ASC").
|
|
| 76 |
all |
|
| 77 |
end |
|
| 28 | 78 |
end |
| app/helpers/news_helper.rb | ||
|---|---|---|
| 1 | 1 |
# encoding: utf-8 |
| 2 | 2 |
# |
| 3 | 3 |
# Redmine - project management software |
| 4 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 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 |
| app/helpers/projects_helper.rb | ||
|---|---|---|
| 1 | 1 |
# encoding: utf-8 |
| 2 | 2 |
# |
| 3 | 3 |
# Redmine - project management software |
| 4 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 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 |
| app/helpers/queries_helper.rb | ||
|---|---|---|
| 1 | 1 |
# encoding: utf-8 |
| 2 | 2 |
# |
| 3 | 3 |
# Redmine - project management software |
| 4 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 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 |
| ... | ... | |
| 24 | 24 |
|
| 25 | 25 |
def filters_options(query) |
| 26 | 26 |
options = [[]] |
| 27 |
sorted_options = query.available_filters.sort do |a, b| |
|
| 28 |
ord = 0 |
|
| 29 |
if !(a[1][:order] == 20 && b[1][:order] == 20) |
|
| 30 |
ord = a[1][:order] <=> b[1][:order] |
|
| 31 |
else |
|
| 32 |
cn = (CustomField::CUSTOM_FIELDS_NAMES.index(a[1][:field].class.name) <=> |
|
| 33 |
CustomField::CUSTOM_FIELDS_NAMES.index(b[1][:field].class.name)) |
|
| 34 |
if cn != 0 |
|
| 35 |
ord = cn |
|
| 36 |
else |
|
| 37 |
f = (a[1][:field] <=> b[1][:field]) |
|
| 38 |
if f != 0 |
|
| 39 |
ord = f |
|
| 40 |
else |
|
| 41 |
# assigned_to or author |
|
| 42 |
ord = (a[0] <=> b[0]) |
|
| 43 |
end |
|
| 44 |
end |
|
| 45 |
end |
|
| 46 |
ord |
|
| 47 |
end |
|
| 48 |
options += sorted_options.map do |field, field_options| |
|
| 27 |
options += query.available_filters.map do |field, field_options| |
|
| 49 | 28 |
[field_options[:name], field] |
| 50 | 29 |
end |
| 51 | 30 |
end |
| 52 | 31 |
|
| 32 |
def query_filters_hidden_tags(query) |
|
| 33 |
tags = ''.html_safe |
|
| 34 |
query.filters.each do |field, options| |
|
| 35 |
tags << hidden_field_tag("f[]", field, :id => nil)
|
|
| 36 |
tags << hidden_field_tag("op[#{field}]", options[:operator], :id => nil)
|
|
| 37 |
options[:values].each do |value| |
|
| 38 |
tags << hidden_field_tag("v[#{field}][]", value, :id => nil)
|
|
| 39 |
end |
|
| 40 |
end |
|
| 41 |
tags |
|
| 42 |
end |
|
| 43 |
|
|
| 44 |
def query_columns_hidden_tags(query) |
|
| 45 |
tags = ''.html_safe |
|
| 46 |
query.columns.each do |column| |
|
| 47 |
tags << hidden_field_tag("c[]", column.name, :id => nil)
|
|
| 48 |
end |
|
| 49 |
tags |
|
| 50 |
end |
|
| 51 |
|
|
| 52 |
def query_hidden_tags(query) |
|
| 53 |
query_filters_hidden_tags(query) + query_columns_hidden_tags(query) |
|
| 54 |
end |
|
| 55 |
|
|
| 53 | 56 |
def available_block_columns_tags(query) |
| 54 | 57 |
tags = ''.html_safe |
| 55 | 58 |
query.available_block_columns.each do |column| |
| ... | ... | |
| 58 | 61 |
tags |
| 59 | 62 |
end |
| 60 | 63 |
|
| 64 |
def query_available_inline_columns_options(query) |
|
| 65 |
(query.available_inline_columns - query.columns).reject(&:frozen?).collect {|column| [column.caption, column.name]}
|
|
| 66 |
end |
|
| 67 |
|
|
| 68 |
def query_selected_inline_columns_options(query) |
|
| 69 |
(query.inline_columns & query.available_inline_columns).reject(&:frozen?).collect {|column| [column.caption, column.name]}
|
|
| 70 |
end |
|
| 71 |
|
|
| 72 |
def render_query_columns_selection(query, options={})
|
|
| 73 |
tag_name = (options[:name] || 'c') + '[]' |
|
| 74 |
render :partial => 'queries/columns', :locals => {:query => query, :tag_name => tag_name}
|
|
| 75 |
end |
|
| 76 |
|
|
| 61 | 77 |
def column_header(column) |
| 62 | 78 |
column.sortable ? sort_header_tag(column.name.to_s, :caption => column.caption, |
| 63 | 79 |
:default_order => column.default_order) : |
| ... | ... | |
| 88 | 104 |
when 'Date' |
| 89 | 105 |
format_date(value) |
| 90 | 106 |
when 'Fixnum' |
| 91 |
if column.name == :done_ratio |
|
| 107 |
if column.name == :id |
|
| 108 |
link_to value, issue_path(issue) |
|
| 109 |
elsif column.name == :done_ratio |
|
| 92 | 110 |
progress_bar(value, :width => '80px') |
| 93 | 111 |
else |
| 94 | 112 |
value.to_s |
| ... | ... | |
| 106 | 124 |
when 'FalseClass' |
| 107 | 125 |
l(:general_text_No) |
| 108 | 126 |
when 'Issue' |
| 109 |
link_to_issue(value, :subject => false)
|
|
| 127 |
value.visible? ? link_to_issue(value) : "##{value.id}"
|
|
| 110 | 128 |
when 'IssueRelation' |
| 111 | 129 |
other = value.other_issue(issue) |
| 112 | 130 |
content_tag('span',
|
| ... | ... | |
| 117 | 135 |
end |
| 118 | 136 |
end |
| 119 | 137 |
|
| 138 |
def csv_content(column, issue) |
|
| 139 |
value = column.value(issue) |
|
| 140 |
if value.is_a?(Array) |
|
| 141 |
value.collect {|v| csv_value(column, issue, v)}.compact.join(', ')
|
|
| 142 |
else |
|
| 143 |
csv_value(column, issue, value) |
|
| 144 |
end |
|
| 145 |
end |
|
| 146 |
|
|
| 147 |
def csv_value(column, issue, value) |
|
| 148 |
case value.class.name |
|
| 149 |
when 'Time' |
|
| 150 |
format_time(value) |
|
| 151 |
when 'Date' |
|
| 152 |
format_date(value) |
|
| 153 |
when 'Float' |
|
| 154 |
sprintf("%.2f", value).gsub('.', l(:general_csv_decimal_separator))
|
|
| 155 |
when 'IssueRelation' |
|
| 156 |
other = value.other_issue(issue) |
|
| 157 |
l(value.label_for(issue)) + " ##{other.id}"
|
|
| 158 |
else |
|
| 159 |
value.to_s |
|
| 160 |
end |
|
| 161 |
end |
|
| 162 |
|
|
| 163 |
def query_to_csv(items, query, options={})
|
|
| 164 |
encoding = l(:general_csv_encoding) |
|
| 165 |
columns = (options[:columns] == 'all' ? query.available_inline_columns : query.inline_columns) |
|
| 166 |
query.available_block_columns.each do |column| |
|
| 167 |
if options[column.name].present? |
|
| 168 |
columns << column |
|
| 169 |
end |
|
| 170 |
end |
|
| 171 |
|
|
| 172 |
export = FCSV.generate(:col_sep => l(:general_csv_separator)) do |csv| |
|
| 173 |
# csv header fields |
|
| 174 |
csv << columns.collect {|c| Redmine::CodesetUtil.from_utf8(c.caption.to_s, encoding) }
|
|
| 175 |
# csv lines |
|
| 176 |
items.each do |item| |
|
| 177 |
csv << columns.collect {|c| Redmine::CodesetUtil.from_utf8(csv_content(c, item), encoding) }
|
|
| 178 |
end |
|
| 179 |
end |
|
| 180 |
export |
|
| 181 |
end |
|
| 182 |
|
|
| 120 | 183 |
# Retrieve query from session or build a new query |
| 121 | 184 |
def retrieve_query |
| 122 | 185 |
if !params[:query_id].blank? |
| 123 | 186 |
cond = "project_id IS NULL" |
| 124 | 187 |
cond << " OR project_id = #{@project.id}" if @project
|
| 125 |
@query = Query.find(params[:query_id], :conditions => cond) |
|
| 188 |
@query = IssueQuery.find(params[:query_id], :conditions => cond)
|
|
| 126 | 189 |
raise ::Unauthorized unless @query.visible? |
| 127 | 190 |
@query.project = @project |
| 128 | 191 |
session[:query] = {:id => @query.id, :project_id => @query.project_id}
|
| 129 | 192 |
sort_clear |
| 130 | 193 |
elsif api_request? || params[:set_filter] || session[:query].nil? || session[:query][:project_id] != (@project ? @project.id : nil) |
| 131 | 194 |
# Give it a name, required to be valid |
| 132 |
@query = Query.new(:name => "_") |
|
| 195 |
@query = IssueQuery.new(:name => "_")
|
|
| 133 | 196 |
@query.project = @project |
| 134 |
build_query_from_params
|
|
| 197 |
@query.build_from_params(params)
|
|
| 135 | 198 |
session[:query] = {:project_id => @query.project_id, :filters => @query.filters, :group_by => @query.group_by, :column_names => @query.column_names}
|
| 136 | 199 |
else |
| 137 | 200 |
# retrieve from session |
| 138 |
@query = Query.find_by_id(session[:query][:id]) if session[:query][:id] |
|
| 139 |
@query ||= Query.new(:name => "_", :filters => session[:query][:filters], :group_by => session[:query][:group_by], :column_names => session[:query][:column_names]) |
|
| 201 |
@query = IssueQuery.find_by_id(session[:query][:id]) if session[:query][:id]
|
|
| 202 |
@query ||= IssueQuery.new(:name => "_", :filters => session[:query][:filters], :group_by => session[:query][:group_by], :column_names => session[:query][:column_names])
|
|
| 140 | 203 |
@query.project = @project |
| 141 | 204 |
end |
| 142 | 205 |
end |
| ... | ... | |
| 144 | 207 |
def retrieve_query_from_session |
| 145 | 208 |
if session[:query] |
| 146 | 209 |
if session[:query][:id] |
| 147 |
@query = Query.find_by_id(session[:query][:id]) |
|
| 210 |
@query = IssueQuery.find_by_id(session[:query][:id])
|
|
| 148 | 211 |
return unless @query |
| 149 | 212 |
else |
| 150 |
@query = Query.new(:name => "_", :filters => session[:query][:filters], :group_by => session[:query][:group_by], :column_names => session[:query][:column_names]) |
|
| 213 |
@query = IssueQuery.new(:name => "_", :filters => session[:query][:filters], :group_by => session[:query][:group_by], :column_names => session[:query][:column_names])
|
|
| 151 | 214 |
end |
| 152 | 215 |
if session[:query].has_key?(:project_id) |
| 153 | 216 |
@query.project_id = session[:query][:project_id] |
| ... | ... | |
| 157 | 220 |
@query |
| 158 | 221 |
end |
| 159 | 222 |
end |
| 160 |
|
|
| 161 |
def build_query_from_params |
|
| 162 |
if params[:fields] || params[:f] |
|
| 163 |
@query.filters = {}
|
|
| 164 |
@query.add_filters(params[:fields] || params[:f], params[:operators] || params[:op], params[:values] || params[:v]) |
|
| 165 |
else |
|
| 166 |
@query.available_filters.keys.each do |field| |
|
| 167 |
@query.add_short_filter(field, params[field]) if params[field] |
|
| 168 |
end |
|
| 169 |
end |
|
| 170 |
@query.group_by = params[:group_by] || (params[:query] && params[:query][:group_by]) |
|
| 171 |
@query.column_names = params[:c] || (params[:query] && params[:query][:column_names]) |
|
| 172 |
end |
|
| 173 | 223 |
end |
| app/helpers/reports_helper.rb | ||
|---|---|---|
| 1 | 1 |
# encoding: utf-8 |
| 2 | 2 |
# |
| 3 | 3 |
# Redmine - project management software |
| 4 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 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 |
| ... | ... | |
| 35 | 35 |
a = aggregate data, criteria |
| 36 | 36 |
a > 0 ? link_to(h(a), *args) : '-' |
| 37 | 37 |
end |
| 38 |
|
|
| 39 |
def aggregate_path(project, field, row, options={})
|
|
| 40 |
parameters = {:set_filter => 1, :subproject_id => '!*', field => row.id}.merge(options)
|
|
| 41 |
project_issues_path(row.is_a?(Project) ? row : project, parameters) |
|
| 42 |
end |
|
| 38 | 43 |
end |
| app/helpers/repositories_helper.rb | ||
|---|---|---|
| 1 | 1 |
# encoding: utf-8 |
| 2 | 2 |
# |
| 3 | 3 |
# Redmine - project management software |
| 4 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 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 |
| ... | ... | |
| 43 | 43 |
end |
| 44 | 44 |
|
| 45 | 45 |
def render_changeset_changes |
| 46 |
changes = @changeset.filechanges.find(:all, :limit => 1000, :order => 'path').collect do |change|
|
|
| 46 |
changes = @changeset.filechanges.limit(1000).reorder('path').all.collect do |change|
|
|
| 47 | 47 |
case change.action |
| 48 | 48 |
when 'A' |
| 49 | 49 |
# Detects moved/copied files |
| app/helpers/roles_helper.rb | ||
|---|---|---|
| 1 | 1 |
# encoding: utf-8 |
| 2 | 2 |
# |
| 3 | 3 |
# Redmine - project management software |
| 4 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 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 |
| app/helpers/routes_helper.rb | ||
|---|---|---|
| 1 |
# encoding: utf-8 |
|
| 2 |
# |
|
| 3 |
# Redmine - project management software |
|
| 4 |
# Copyright (C) 2006-2013 Jean-Philippe Lang |
|
| 5 |
# |
|
| 6 |
# This program is free software; you can redistribute it and/or |
|
| 7 |
# modify it under the terms of the GNU General Public License |
|
| 8 |
# as published by the Free Software Foundation; either version 2 |
|
| 9 |
# of the License, or (at your option) any later version. |
|
| 10 |
# |
|
| 11 |
# This program is distributed in the hope that it will be useful, |
|
| 12 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 13 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 14 |
# GNU General Public License for more details. |
|
| 15 |
# |
|
| 16 |
# You should have received a copy of the GNU General Public License |
|
| 17 |
# along with this program; if not, write to the Free Software |
|
| 18 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
| 19 |
|
|
| 20 |
module RoutesHelper |
|
| 21 |
|
|
| 22 |
# Returns the path to project issues or to the cross-project |
|
| 23 |
# issue list if project is nil |
|
| 24 |
def _project_issues_path(project, *args) |
|
| 25 |
if project |
|
| 26 |
project_issues_path(project, *args) |
|
| 27 |
else |
|
| 28 |
issues_path(*args) |
|
| 29 |
end |
|
| 30 |
end |
|
| 31 |
|
|
| 32 |
def _project_calendar_path(project, *args) |
|
| 33 |
project ? project_calendar_path(project, *args) : issues_calendar_path(*args) |
|
| 34 |
end |
|
| 35 |
|
|
| 36 |
def _project_gantt_path(project, *args) |
|
| 37 |
project ? project_gantt_path(project, *args) : issues_gantt_path(*args) |
|
| 38 |
end |
|
| 39 |
end |
|
| app/helpers/search_helper.rb | ||
|---|---|---|
| 1 | 1 |
# encoding: utf-8 |
| 2 | 2 |
# |
| 3 | 3 |
# Redmine - project management software |
| 4 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 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 |
| app/helpers/settings_helper.rb | ||
|---|---|---|
| 1 | 1 |
# encoding: utf-8 |
| 2 | 2 |
# |
| 3 | 3 |
# Redmine - project management software |
| 4 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 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 |
| ... | ... | |
| 53 | 53 |
check_box_tag( |
| 54 | 54 |
"settings[#{setting}][]",
|
| 55 | 55 |
value, |
| 56 |
Setting.send(setting).include?(value),
|
|
| 56 |
setting_values.include?(value),
|
|
| 57 | 57 |
:id => nil |
| 58 | 58 |
) + text.to_s, |
| 59 | 59 |
:class => (options[:inline] ? 'inline' : 'block') |
| app/helpers/sort_helper.rb | ||
|---|---|---|
| 80 | 80 |
@criteria.collect {|k,o| k + (o ? '' : ':desc')}.join(',')
|
| 81 | 81 |
end |
| 82 | 82 |
|
| 83 |
# Returns an array of SQL fragments used to sort the list |
|
| 83 | 84 |
def to_sql |
| 84 | 85 |
sql = @criteria.collect do |k,o| |
| 85 | 86 |
if s = @available_criteria[k] |
| 86 |
(o ? s.to_a : s.to_a.collect {|c| append_desc(c)}).join(', ')
|
|
| 87 |
(o ? s.to_a : s.to_a.collect {|c| append_desc(c)})
|
|
| 87 | 88 |
end |
| 88 |
end.compact.join(', ')
|
|
| 89 |
end.flatten.compact
|
|
| 89 | 90 |
sql.blank? ? nil : sql |
| 90 | 91 |
end |
| 91 | 92 |
|
| app/helpers/timelog_helper.rb | ||
|---|---|---|
| 1 | 1 |
# encoding: utf-8 |
| 2 | 2 |
# |
| 3 | 3 |
# Redmine - project management software |
| 4 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 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 |
| ... | ... | |
| 56 | 56 |
end |
| 57 | 57 |
|
| 58 | 58 |
def select_hours(data, criteria, value) |
| 59 |
if value.to_s.empty?
|
|
| 60 |
data.select {|row| row[criteria].blank? }
|
|
| 59 |
if value.to_s.empty?
|
|
| 60 |
data.select {|row| row[criteria].blank? }
|
|
| 61 | 61 |
else |
| 62 |
data.select {|row| row[criteria].to_s == value.to_s}
|
|
| 62 |
data.select {|row| row[criteria].to_s == value.to_s}
|
|
| 63 | 63 |
end |
| 64 | 64 |
end |
| 65 | 65 |
|
| ... | ... | |
| 86 | 86 |
value) |
| 87 | 87 |
end |
| 88 | 88 |
|
| 89 |
def entries_to_csv(entries) |
|
| 90 |
decimal_separator = l(:general_csv_decimal_separator) |
|
| 91 |
custom_fields = TimeEntryCustomField.find(:all) |
|
| 92 |
export = FCSV.generate(:col_sep => l(:general_csv_separator)) do |csv| |
|
| 93 |
# csv header fields |
|
| 94 |
headers = [l(:field_spent_on), |
|
| 95 |
l(:field_user), |
|
| 96 |
l(:field_activity), |
|
| 97 |
l(:field_project), |
|
| 98 |
l(:field_issue), |
|
| 99 |
l(:field_tracker), |
|
| 100 |
l(:field_subject), |
|
| 101 |
l(:field_hours), |
|
| 102 |
l(:field_comments) |
|
| 103 |
] |
|
| 104 |
# Export custom fields |
|
| 105 |
headers += custom_fields.collect(&:name) |
|
| 106 |
|
|
| 107 |
csv << headers.collect {|c| Redmine::CodesetUtil.from_utf8(
|
|
| 108 |
c.to_s, |
|
| 109 |
l(:general_csv_encoding) ) } |
|
| 110 |
# csv lines |
|
| 111 |
entries.each do |entry| |
|
| 112 |
fields = [format_date(entry.spent_on), |
|
| 113 |
entry.user, |
|
| 114 |
entry.activity, |
|
| 115 |
entry.project, |
|
| 116 |
(entry.issue ? entry.issue.id : nil), |
|
| 117 |
(entry.issue ? entry.issue.tracker : nil), |
|
| 118 |
(entry.issue ? entry.issue.subject : nil), |
|
| 119 |
entry.hours.to_s.gsub('.', decimal_separator),
|
|
| 120 |
entry.comments |
|
| 121 |
] |
|
| 122 |
fields += custom_fields.collect {|f| show_value(entry.custom_field_values.detect {|v| v.custom_field_id == f.id}) }
|
|
| 123 |
|
|
| 124 |
csv << fields.collect {|c| Redmine::CodesetUtil.from_utf8(
|
|
| 125 |
c.to_s, |
|
| 126 |
l(:general_csv_encoding) ) } |
|
| 127 |
end |
|
| 128 |
end |
|
| 129 |
export |
|
| 130 |
end |
|
| 131 |
|
|
| 132 | 89 |
def format_criteria_value(criteria_options, value) |
| 133 | 90 |
if value.blank? |
| 134 | 91 |
"[#{l(:label_none)}]"
|
| ... | ... | |
| 150 | 107 |
# Column headers |
| 151 | 108 |
headers = report.criteria.collect {|criteria| l(report.available_criteria[criteria][:label]) }
|
| 152 | 109 |
headers += report.periods |
| 153 |
headers << l(:label_total) |
|
| 110 |
headers << l(:label_total_time)
|
|
| 154 | 111 |
csv << headers.collect {|c| Redmine::CodesetUtil.from_utf8(
|
| 155 | 112 |
c.to_s, |
| 156 | 113 |
l(:general_csv_encoding) ) } |
| 157 | 114 |
# Content |
| 158 | 115 |
report_criteria_to_csv(csv, report.available_criteria, report.columns, report.criteria, report.periods, report.hours) |
| 159 | 116 |
# Total row |
| 160 |
str_total = Redmine::CodesetUtil.from_utf8(l(:label_total), l(:general_csv_encoding)) |
|
| 117 |
str_total = Redmine::CodesetUtil.from_utf8(l(:label_total_time), l(:general_csv_encoding))
|
|
| 161 | 118 |
row = [ str_total ] + [''] * (report.criteria.size - 1) |
| 162 | 119 |
total = 0 |
| 163 | 120 |
report.periods.each do |period| |
| app/helpers/trackers_helper.rb | ||
|---|---|---|
| 1 | 1 |
# encoding: utf-8 |
| 2 | 2 |
# |
| 3 | 3 |
# Redmine - project management software |
| 4 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 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 |
| app/helpers/users_helper.rb | ||
|---|---|---|
| 1 | 1 |
# encoding: utf-8 |
| 2 | 2 |
# |
| 3 | 3 |
# Redmine - project management software |
| 4 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 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 |
| app/helpers/versions_helper.rb | ||
|---|---|---|
| 1 | 1 |
# encoding: utf-8 |
| 2 | 2 |
# |
| 3 | 3 |
# Redmine - project management software |
| 4 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 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 |
| app/helpers/watchers_helper.rb | ||
|---|---|---|
| 1 | 1 |
# encoding: utf-8 |
| 2 | 2 |
# |
| 3 | 3 |
# Redmine - project management software |
| 4 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 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 |
| ... | ... | |
| 20 | 20 |
module WatchersHelper |
| 21 | 21 |
|
| 22 | 22 |
def watcher_tag(object, user, options={})
|
| 23 |
content_tag("span", watcher_link(object, user), :class => watcher_css(object))
|
|
| 23 |
ActiveSupport::Deprecation.warn "#watcher_tag is deprecated and will be removed in Redmine 3.0. Use #watcher_link instead." |
|
| 24 |
watcher_link(object, user) |
|
| 24 | 25 |
end |
| 25 | 26 |
|
| 26 |
def watcher_link(object, user) |
|
| 27 |
return '' unless user && user.logged? && object.respond_to?('watched_by?')
|
|
| 28 |
watched = object.watched_by?(user) |
|
| 29 |
url = {:controller => 'watchers',
|
|
| 30 |
:action => (watched ? 'unwatch' : 'watch'), |
|
| 31 |
:object_type => object.class.to_s.underscore, |
|
| 32 |
:object_id => object.id} |
|
| 33 |
link_to((watched ? l(:button_unwatch) : l(:button_watch)), url, |
|
| 34 |
:remote => true, :method => 'post', :class => (watched ? 'icon icon-fav' : 'icon icon-fav-off')) |
|
| 27 |
def watcher_link(objects, user) |
|
| 28 |
return '' unless user && user.logged? |
|
| 29 |
objects = Array.wrap(objects) |
|
| 35 | 30 |
|
| 31 |
watched = objects.any? {|object| object.watched_by?(user)}
|
|
| 32 |
css = [watcher_css(objects), watched ? 'icon icon-fav' : 'icon icon-fav-off'].join(' ')
|
|
| 33 |
text = watched ? l(:button_unwatch) : l(:button_watch) |
|
| 34 |
url = watch_path( |
|
| 35 |
:object_type => objects.first.class.to_s.underscore, |
|
| 36 |
:object_id => (objects.size == 1 ? objects.first.id : objects.map(&:id).sort) |
|
| 37 |
) |
|
| 38 |
method = watched ? 'delete' : 'post' |
|
| 39 |
|
|
| 40 |
link_to text, url, :remote => true, :method => method, :class => css |
|
| 36 | 41 |
end |
| 37 | 42 |
|
| 38 | 43 |
# Returns the css class used to identify watch links for a given +object+ |
| 39 |
def watcher_css(object) |
|
| 40 |
"#{object.class.to_s.underscore}-#{object.id}-watcher"
|
|
| 44 |
def watcher_css(objects) |
|
| 45 |
objects = Array.wrap(objects) |
|
| 46 |
id = (objects.size == 1 ? objects.first.id : 'bulk') |
|
| 47 |
"#{objects.first.class.to_s.underscore}-#{id}-watcher"
|
|
| 41 | 48 |
end |
| 42 | 49 |
|
| 43 | 50 |
# Returns a comma separated list of users watching the given object |
| ... | ... | |
| 56 | 63 |
:user_id => user} |
| 57 | 64 |
s << ' ' |
| 58 | 65 |
s << link_to(image_tag('delete.png'), url,
|
| 59 |
:remote => true, :method => 'post', :style => "vertical-align: middle", :class => "delete")
|
|
| 66 |
:remote => true, :method => 'delete', :class => "delete")
|
|
| 60 | 67 |
end |
| 61 |
content << content_tag('li', s)
|
|
| 68 |
content << content_tag('li', s, :class => "user-#{user.id}")
|
|
| 62 | 69 |
end |
| 63 |
content.present? ? content_tag('ul', content) : content
|
|
| 70 |
content.present? ? content_tag('ul', content, :class => 'watchers') : content
|
|
| 64 | 71 |
end |
| 65 | 72 |
|
| 66 | 73 |
def watchers_checkboxes(object, users, checked=nil) |
| app/helpers/welcome_helper.rb | ||
|---|---|---|
| 1 | 1 |
# encoding: utf-8 |
| 2 | 2 |
# |
| 3 | 3 |
# Redmine - project management software |
| 4 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 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 |
| app/helpers/wiki_helper.rb | ||
|---|---|---|
| 1 | 1 |
# encoding: utf-8 |
| 2 | 2 |
# |
| 3 | 3 |
# Redmine - project management software |
| 4 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 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 |
| app/helpers/workflows_helper.rb | ||
|---|---|---|
| 1 | 1 |
# encoding: utf-8 |
| 2 | 2 |
# |
| 3 | 3 |
# Redmine - project management software |
| 4 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 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 |
Also available in: Unified diff