Nuevo plugin Redmine Checklist 3.1.10 light

This commit is contained in:
Manuel Cillero 2018-02-04 19:51:03 +01:00
parent 294bc87e76
commit ef5521e0a2
65 changed files with 3544 additions and 0 deletions

View file

@ -0,0 +1,31 @@
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
# issue checklists management plugin for Redmine
#
# Copyright (C) 2011-2017 RedmineUP
# http://www.redmineup.com/
#
# redmine_checklists 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 3 of the License, or
# (at your option) any later version.
#
# redmine_checklists 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.
#
# You should have received a copy of the GNU General Public License
# along with redmine_checklists. If not, see <http://www.gnu.org/licenses/>.
module RedmineChecklists
module Hooks
class ControllerIssuesHook < Redmine::Hook::ViewListener
def controller_issues_edit_after_save(context = {})
if (Setting.issue_done_ratio == "issue_field") && RedmineChecklists.settings["issue_done_ratio"].to_i > 0
Checklist.recalc_issue_done_ratio(context[:issue].id)
end
end
end
end
end

View file

@ -0,0 +1,27 @@
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
# issue checklists management plugin for Redmine
#
# Copyright (C) 2011-2017 RedmineUP
# http://www.redmineup.com/
#
# redmine_checklists 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 3 of the License, or
# (at your option) any later version.
#
# redmine_checklists 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.
#
# You should have received a copy of the GNU General Public License
# along with redmine_checklists. If not, see <http://www.gnu.org/licenses/>.
module RedmineChecklists
module Hooks
class ViewsIssuesHook < Redmine::Hook::ViewListener
render_on :view_issues_show_description_bottom, :partial => "issues/checklist"
render_on :view_issues_form_details_bottom, :partial => "issues/checklist_form"
end
end
end

View file

@ -0,0 +1,29 @@
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
# issue checklists management plugin for Redmine
#
# Copyright (C) 2011-2017 RedmineUP
# http://www.redmineup.com/
#
# redmine_checklists 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 3 of the License, or
# (at your option) any later version.
#
# redmine_checklists 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.
#
# You should have received a copy of the GNU General Public License
# along with redmine_checklists. If not, see <http://www.gnu.org/licenses/>.
module RedmineChecklists
module Hooks
class ViewsLayoutsHook < Redmine::Hook::ViewListener
def view_layouts_base_html_head(context={})
return javascript_include_tag(:checklists, :plugin => 'redmine_checklists') +
stylesheet_link_tag(:checklists, :plugin => 'redmine_checklists')
end
end
end
end

View file

@ -0,0 +1,33 @@
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
# issue checklists management plugin for Redmine
#
# Copyright (C) 2011-2017 RedmineUP
# http://www.redmineup.com/
#
# redmine_checklists 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 3 of the License, or
# (at your option) any later version.
#
# redmine_checklists 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.
#
# You should have received a copy of the GNU General Public License
# along with redmine_checklists. If not, see <http://www.gnu.org/licenses/>.
module RedmineChecklists
module Patches
module AddHelpersForChecklistPatch
def self.apply(controller)
controller.send(:helper, 'checklists')
end
end
end
end
[IssuesController].each do |controller|
RedmineChecklists::Patches::AddHelpersForChecklistPatch.apply(controller)
end

View file

@ -0,0 +1,275 @@
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
# issue checklists management plugin for Redmine
#
# Copyright (C) 2011-2017 RedmineUP
# http://www.redmineup.com/
#
# redmine_checklists 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 3 of the License, or
# (at your option) any later version.
#
# redmine_checklists 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.
#
# You should have received a copy of the GNU General Public License
# along with redmine_checklists. If not, see <http://www.gnu.org/licenses/>.
module Redmine
module ApiTest
# Base class for API tests
class Base < ActionDispatch::IntegrationTest
# Test that a request allows the three types of API authentication
#
# * HTTP Basic with username and password
# * HTTP Basic with an api key for the username
# * Key based with the key=X parameter
#
# @param [Symbol] http_method the HTTP method for request (:get, :post, :put, :delete)
# @param [String] url the request url
# @param [optional, Hash] parameters additional request parameters
# @param [optional, Hash] options additional options
# @option options [Symbol] :success_code Successful response code (:success)
# @option options [Symbol] :failure_code Failure response code (:unauthorized)
def self.should_allow_api_authentication(http_method, url, parameters={}, options={})
should_allow_http_basic_auth_with_username_and_password(http_method, url, parameters, options)
should_allow_http_basic_auth_with_key(http_method, url, parameters, options)
should_allow_key_based_auth(http_method, url, parameters, options)
end
# Test that a request allows the username and password for HTTP BASIC
#
# @param [Symbol] http_method the HTTP method for request (:get, :post, :put, :delete)
# @param [String] url the request url
# @param [optional, Hash] parameters additional request parameters
# @param [optional, Hash] options additional options
# @option options [Symbol] :success_code Successful response code (:success)
# @option options [Symbol] :failure_code Failure response code (:unauthorized)
def self.should_allow_http_basic_auth_with_username_and_password(http_method, url, parameters={}, options={})
success_code = options[:success_code] || :success
failure_code = options[:failure_code] || :unauthorized
context "should allow http basic auth using a username and password for #{http_method} #{url}" do
context "with a valid HTTP authentication" do
setup do
@user = User.generate! do |user|
user.admin = true
user.password = 'my_password'
end
send(http_method, url, parameters, credentials(@user.login, 'my_password'))
end
should_respond_with success_code
should_respond_with_content_type_based_on_url(url)
should "login as the user" do
assert_equal @user, User.current
end
end
context "with an invalid HTTP authentication" do
setup do
@user = User.generate!
send(http_method, url, parameters, credentials(@user.login, 'wrong_password'))
end
should_respond_with failure_code
should_respond_with_content_type_based_on_url(url)
should "not login as the user" do
assert_equal User.anonymous, User.current
end
end
context "without credentials" do
setup do
send(http_method, url, parameters)
end
should_respond_with failure_code
should_respond_with_content_type_based_on_url(url)
should "include_www_authenticate_header" do
assert @controller.response.headers.has_key?('WWW-Authenticate')
end
end
end
end
# Test that a request allows the API key with HTTP BASIC
#
# @param [Symbol] http_method the HTTP method for request (:get, :post, :put, :delete)
# @param [String] url the request url
# @param [optional, Hash] parameters additional request parameters
# @param [optional, Hash] options additional options
# @option options [Symbol] :success_code Successful response code (:success)
# @option options [Symbol] :failure_code Failure response code (:unauthorized)
def self.should_allow_http_basic_auth_with_key(http_method, url, parameters={}, options={})
success_code = options[:success_code] || :success
failure_code = options[:failure_code] || :unauthorized
context "should allow http basic auth with a key for #{http_method} #{url}" do
context "with a valid HTTP authentication using the API token" do
setup do
@user = User.generate! do |user|
user.admin = true
end
@token = Token.create!(:user => @user, :action => 'api')
send(http_method, url, parameters, credentials(@token.value, 'X'))
end
should_respond_with success_code
should_respond_with_content_type_based_on_url(url)
should_be_a_valid_response_string_based_on_url(url)
should "login as the user" do
assert_equal @user, User.current
end
end
context "with an invalid HTTP authentication" do
setup do
@user = User.generate!
@token = Token.create!(:user => @user, :action => 'feeds')
send(http_method, url, parameters, credentials(@token.value, 'X'))
end
should_respond_with failure_code
should_respond_with_content_type_based_on_url(url)
should "not login as the user" do
assert_equal User.anonymous, User.current
end
end
end
end
# Test that a request allows full key authentication
#
# @param [Symbol] http_method the HTTP method for request (:get, :post, :put, :delete)
# @param [String] url the request url, without the key=ZXY parameter
# @param [optional, Hash] parameters additional request parameters
# @param [optional, Hash] options additional options
# @option options [Symbol] :success_code Successful response code (:success)
# @option options [Symbol] :failure_code Failure response code (:unauthorized)
def self.should_allow_key_based_auth(http_method, url, parameters={}, options={})
success_code = options[:success_code] || :success
failure_code = options[:failure_code] || :unauthorized
context "should allow key based auth using key=X for #{http_method} #{url}" do
context "with a valid api token" do
setup do
@user = User.generate! do |user|
user.admin = true
end
@token = Token.create!(:user => @user, :action => 'api')
# Simple url parse to add on ?key= or &key=
request_url = if url.match(/\?/)
url + "&key=#{@token.value}"
else
url + "?key=#{@token.value}"
end
send(http_method, request_url, parameters)
end
should_respond_with success_code
should_respond_with_content_type_based_on_url(url)
should_be_a_valid_response_string_based_on_url(url)
should "login as the user" do
assert_equal @user, User.current
end
end
context "with an invalid api token" do
setup do
@user = User.generate! do |user|
user.admin = true
end
@token = Token.create!(:user => @user, :action => 'feeds')
# Simple url parse to add on ?key= or &key=
request_url = if url.match(/\?/)
url + "&key=#{@token.value}"
else
url + "?key=#{@token.value}"
end
send(http_method, request_url, parameters)
end
should_respond_with failure_code
should_respond_with_content_type_based_on_url(url)
should "not login as the user" do
assert_equal User.anonymous, User.current
end
end
end
context "should allow key based auth using X-Redmine-API-Key header for #{http_method} #{url}" do
setup do
@user = User.generate! do |user|
user.admin = true
end
@token = Token.create!(:user => @user, :action => 'api')
send(http_method, url, parameters, {'X-Redmine-API-Key' => @token.value.to_s})
end
should_respond_with success_code
should_respond_with_content_type_based_on_url(url)
should_be_a_valid_response_string_based_on_url(url)
should "login as the user" do
assert_equal @user, User.current
end
end
end
# Uses should_respond_with_content_type based on what's in the url:
#
# '/project/issues.xml' => should_respond_with_content_type :xml
# '/project/issues.json' => should_respond_with_content_type :json
#
# @param [String] url Request
def self.should_respond_with_content_type_based_on_url(url)
case
when url.match(/xml/i)
should "respond with XML" do
assert_equal 'application/xml', @response.content_type
end
when url.match(/json/i)
should "respond with JSON" do
assert_equal 'application/json', @response.content_type
end
else
raise "Unknown content type for should_respond_with_content_type_based_on_url: #{url}"
end
end
# Uses the url to assert which format the response should be in
#
# '/project/issues.xml' => should_be_a_valid_xml_string
# '/project/issues.json' => should_be_a_valid_json_string
#
# @param [String] url Request
def self.should_be_a_valid_response_string_based_on_url(url)
case
when url.match(/xml/i)
should_be_a_valid_xml_string
when url.match(/json/i)
should_be_a_valid_json_string
else
raise "Unknown content type for should_be_a_valid_response_based_on_url: #{url}"
end
end
# Checks that the response is a valid JSON string
def self.should_be_a_valid_json_string
should "be a valid JSON string (or empty)" do
assert(response.body.blank? || ActiveSupport::JSON.decode(response.body))
end
end
# Checks that the response is a valid XML string
def self.should_be_a_valid_xml_string
should "be a valid XML string" do
assert REXML::Document.new(response.body)
end
end
def self.should_respond_with(status)
should "respond with #{status}" do
assert_response status
end
end
end
end
end

View file

@ -0,0 +1,69 @@
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
# issue checklists management plugin for Redmine
#
# Copyright (C) 2011-2017 RedmineUP
# http://www.redmineup.com/
#
# redmine_checklists 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 3 of the License, or
# (at your option) any later version.
#
# redmine_checklists 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.
#
# You should have received a copy of the GNU General Public License
# along with redmine_checklists. If not, see <http://www.gnu.org/licenses/>.
require_dependency 'journal'
module RedmineChecklists
module Patches
module JournalPatch
def self.included(base) # :nodoc:
base.send(:include, InstanceMethods)
base.class_eval do
end
end
module InstanceMethods
if Redmine::VERSION.to_s < '2.6'
def send_notification
if notify? &&
(Setting.notified_events.include?('issue_updated') ||
(Setting.notified_events.include?('issue_note_added') && notes.present?) ||
(Setting.notified_events.include?('issue_status_updated') && new_status.present?) ||
(Setting.notified_events.include?('issue_priority_updated') && new_value_for('priority_id').present?)
)
checklist_email_nootification(self).deliver
end
end
def detail_for_attribute(attribute)
details.detect { |detail| detail.prop_key == attribute }
end
end
def checklist_email_nootification(journal)
if Redmine::VERSION.to_s < '2.4'
Mailer.issue_edit(journal)
else
to_users = Redmine::VERSION.to_s <= '3.0' ? journal.notified_users : journal.recipients
cc_users = Redmine::VERSION.to_s <= '3.0' ? journal.notified_watchers - to_users : journal.watcher_recipients - to_users
Mailer.issue_edit(journal, to_users, cc_users)
end
end
end
end
end
end
unless Journal.included_modules.include?(RedmineChecklists::Patches::JournalPatch)
Journal.send(:include, RedmineChecklists::Patches::JournalPatch)
end

View file

@ -0,0 +1,37 @@
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
# issue checklists management plugin for Redmine
#
# Copyright (C) 2011-2017 RedmineUP
# http://www.redmineup.com/
#
# redmine_checklists 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 3 of the License, or
# (at your option) any later version.
#
# redmine_checklists 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.
#
# You should have received a copy of the GNU General Public License
# along with redmine_checklists. If not, see <http://www.gnu.org/licenses/>.
class OpenStruct2 < OpenStruct
undef id if defined?(id)
def to_h
json
end
def [](key)
json[key.to_s]
end
def json
return @json if @json
@json = JSON.parse(to_json)
@json = @json['table'] if @json.has_key?('table')
@json
end
end

View file

@ -0,0 +1,22 @@
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
# issue checklists management plugin for Redmine
#
# Copyright (C) 2011-2017 RedmineUP
# http://www.redmineup.com/
#
# redmine_checklists 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 3 of the License, or
# (at your option) any later version.
#
# redmine_checklists 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.
#
# You should have received a copy of the GNU General Public License
# along with redmine_checklists. If not, see <http://www.gnu.org/licenses/>.
if Redmine::VERSION.to_s < '2.3'
Dir[File.dirname(__FILE__) + '/compatibility/2.1/*.rb'].each { |f| require f }
end

View file

@ -0,0 +1,74 @@
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
# issue checklists management plugin for Redmine
#
# Copyright (C) 2011-2017 RedmineUP
# http://www.redmineup.com/
#
# redmine_checklists 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 3 of the License, or
# (at your option) any later version.
#
# redmine_checklists 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.
#
# You should have received a copy of the GNU General Public License
# along with redmine_checklists. If not, see <http://www.gnu.org/licenses/>.
require_dependency 'issue'
module RedmineChecklists
module Patches
module IssuePatch
def self.included(base) # :nodoc:
base.send(:include, InstanceMethods)
base.class_eval do
unloadable # Send unloadable so it will not be unloaded in development
attr_accessor :old_checklists
attr_reader :copied_from
alias_method_chain :copy, :checklist
after_save :copy_subtask_checklists
if ActiveRecord::VERSION::MAJOR >= 4
has_many :checklists, lambda { order("#{Checklist.table_name}.position") }, :class_name => "Checklist", :dependent => :destroy, :inverse_of => :issue
else
has_many :checklists, :class_name => "Checklist", :dependent => :destroy, :inverse_of => :issue,
:order => 'position'
end
accepts_nested_attributes_for :checklists, :allow_destroy => true, :reject_if => proc { |attrs| attrs["subject"].blank? }
safe_attributes 'checklists_attributes',
:if => lambda {|issue, user| (user.allowed_to?(:done_checklists, issue.project) ||
user.allowed_to?(:edit_checklists, issue.project))}
def copy_checklists(arg)
issue = arg.is_a?(Issue) ? arg : Issue.visible.find(arg)
issue.checklists.each{ |checklist| Checklist.create(checklist.attributes.except('id','issue_id').merge(:issue => self)) } if issue
end
end
end
module InstanceMethods
def copy_subtask_checklists
return if !copy? || parent_id.nil? || checklists.any?
copy_checklists(@copied_from)
end
def copy_with_checklist(attributes = nil, copy_options = {})
copy = copy_without_checklist(attributes, copy_options)
copy.copy_checklists(self)
copy
end
end
end
end
end
unless Issue.included_modules.include?(RedmineChecklists::Patches::IssuePatch)
Issue.send(:include, RedmineChecklists::Patches::IssuePatch)
end

View file

@ -0,0 +1,37 @@
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
# issue checklists management plugin for Redmine
#
# Copyright (C) 2011-2017 RedmineUP
# http://www.redmineup.com/
#
# redmine_checklists 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 3 of the License, or
# (at your option) any later version.
#
# redmine_checklists 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.
#
# You should have received a copy of the GNU General Public License
# along with redmine_checklists. If not, see <http://www.gnu.org/licenses/>.
require_dependency 'query'
module RedmineChecklists
module Patches
module IssueQueryPatch
def self.included(base)
base.send(:include, InstanceMethods)
end
module InstanceMethods
end
end
end
end
unless IssueQuery.included_modules.include?(RedmineChecklists::Patches::IssueQueryPatch)
IssueQuery.send(:include, RedmineChecklists::Patches::IssueQueryPatch)
end

View file

@ -0,0 +1,76 @@
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
# issue checklists management plugin for Redmine
#
# Copyright (C) 2011-2017 RedmineUP
# http://www.redmineup.com/
#
# redmine_checklists 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 3 of the License, or
# (at your option) any later version.
#
# redmine_checklists 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.
#
# You should have received a copy of the GNU General Public License
# along with redmine_checklists. If not, see <http://www.gnu.org/licenses/>.
module RedmineChecklists
module Patches
module IssuesControllerPatch
def self.included(base) # :nodoc:
base.send(:include, InstanceMethods)
base.class_eval do
unloadable # Send unloadable so it will not be unloaded in development
alias_method_chain :build_new_issue_from_params, :checklist
before_filter :save_before_state, :only => [:update]
end
end
module InstanceMethods
def build_new_issue_from_params_with_checklist
if params[:id].blank?
if params[:copy_from].blank?
else
fill_checklist_attributes
end
end
build_new_issue_from_params_without_checklist
end
def save_before_state
@issue.old_checklists = @issue.checklists.to_json
end
def fill_checklist_attributes
return unless params[:issue].blank?
begin
@copy_from = Issue.visible.find(params[:copy_from])
add_checklists_to_params(@copy_from.checklists)
rescue ActiveRecord::RecordNotFound
render_404
return
end
end
def add_checklists_to_params(checklists)
params[:issue].blank? ? params[:issue] = { :checklists_attributes => {} } : params[:issue][:checklists_attributes] = {}
checklists.each_with_index do |checklist_item, index|
params[:issue][:checklists_attributes][index.to_s] = { :is_done => checklist_item.is_done,
:subject => checklist_item.subject,
:position => checklist_item.position }
end
end
end
end
end
end
unless IssuesController.included_modules.include?(RedmineChecklists::Patches::IssuesControllerPatch)
IssuesController.send(:include, RedmineChecklists::Patches::IssuesControllerPatch)
end

View file

@ -0,0 +1,90 @@
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
# issue checklists management plugin for Redmine
#
# Copyright (C) 2011-2017 RedmineUP
# http://www.redmineup.com/
#
# redmine_checklists 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 3 of the License, or
# (at your option) any later version.
#
# redmine_checklists 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.
#
# You should have received a copy of the GNU General Public License
# along with redmine_checklists. If not, see <http://www.gnu.org/licenses/>.
module RedmineChecklists
module Patches
module IssuesHelperPatch
def self.included(base)
base.send(:include, InstanceMethods)
base.class_eval do
unloadable
alias_method_chain :details_to_strings, :checklists
alias_method_chain :render_email_issue_attributes, :checklists if Redmine::VERSION.to_s <= '2.4' && Redmine::VERSION.to_s >= '2.2'
end
end
module InstanceMethods
def render_email_issue_attributes_with_checklists(issue, html = false)
journal = issue.journals.order(:id).last
return render_email_issue_attributes_without_checklists(issue, html) unless journal
details = journal.details
return render_email_issue_attributes_without_checklists(issue, html) unless details
checklist_details = details.select{ |x| x.prop_key == 'checklist'}
return render_email_issue_attributes_without_checklists(issue, html) unless checklist_details.any?
return render_email_issue_attributes_without_checklists(issue, html) + details_to_strings_with_checklists(checklist_details, !html).join(html ? "<br/>".html_safe : "\n")
end
def details_to_strings_with_checklists(details, no_html = false, options = {})
details_checklist, details_other = details.partition{ |x| x.prop_key == 'checklist' }
details_checklist.map do |detail|
result = []
diff = Hash.new([])
if Checklist.old_format?(detail)
result << "<b>#{l(:label_checklist_item)}</b> #{l(:label_checklist_changed_from)} #{detail.old_value} #{l(:label_checklist_changed_to)} #{detail.value}"
else
diff = JournalChecklistHistory.new(detail.old_value, detail.value).diff
end
if diff[:done].any?
diff[:done].each do |item|
result << "<b>#{ERB::Util.h l(:label_checklist_item)}</b> <input type='checkbox' #{item.is_done ? 'checked' : '' } disabled> <i>#{ERB::Util.h item[:subject]}</i> #{ERB::Util.h l(:label_checklist_done)}"
end
end
if diff[:undone].any?
diff[:undone].each do |item|
result << "<b>#{ERB::Util.h l(:label_checklist_item)}</b> <input type='checkbox' #{item.is_done ? 'checked' : '' } disabled> <i>#{ERB::Util.h item[:subject]}</i> #{ERB::Util.h l(:label_checklist_undone)}"
end
end
result = result.join('</li><li>').html_safe
result = nil if result.blank?
if result && no_html
result = result.gsub /<\/li><li>/, "\n"
result = result.gsub /<input type='checkbox'[^c^>]*checked[^>]*>/, '[x]'
result = result.gsub /<input type='checkbox'[^c^>]*>/, '[ ]'
result = result.gsub /<[^>]*>/, ''
result = CGI.unescapeHTML(result)
end
result
end.compact + details_to_strings_without_checklists(details_other, no_html, options)
end
end
end
end
end
unless IssuesHelper.included_modules.include?(RedmineChecklists::Patches::IssuesHelperPatch)
IssuesHelper.send(:include, RedmineChecklists::Patches::IssuesHelperPatch)
end

View file

@ -0,0 +1,20 @@
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
# issue checklists management plugin for Redmine
#
# Copyright (C) 2011-2017 RedmineUP
# http://www.redmineup.com/
#
# redmine_checklists 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 3 of the License, or
# (at your option) any later version.
#
# redmine_checklists 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.
#
# You should have received a copy of the GNU General Public License
# along with redmine_checklists. If not, see <http://www.gnu.org/licenses/>.

View file

@ -0,0 +1,46 @@
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
# issue checklists management plugin for Redmine
#
# Copyright (C) 2011-2017 RedmineUP
# http://www.redmineup.com/
#
# redmine_checklists 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 3 of the License, or
# (at your option) any later version.
#
# redmine_checklists 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.
#
# You should have received a copy of the GNU General Public License
# along with redmine_checklists. If not, see <http://www.gnu.org/licenses/>.
require_dependency 'project'
module RedmineChecklists
module Patches
module ProjectPatch
def self.included(base) # :nodoc:
base.send(:include, InstanceMethods)
base.class_eval do
unloadable # Send unloadable so it will not be unloaded in development
alias_method_chain :copy_issues, :checklist
end
end
module InstanceMethods
def copy_issues_with_checklist(project)
copy_issues_without_checklist(project)
issues.each{ |issue| issue.copy_checklists(issue.copied_from)}
end
end
end
end
end
unless Project.included_modules.include?(RedmineChecklists::Patches::ProjectPatch)
Project.send(:include, RedmineChecklists::Patches::ProjectPatch)
end

View file

@ -0,0 +1,37 @@
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
# issue checklists management plugin for Redmine
#
# Copyright (C) 2011-2017 RedmineUP
# http://www.redmineup.com/
#
# redmine_checklists 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 3 of the License, or
# (at your option) any later version.
#
# redmine_checklists 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.
#
# You should have received a copy of the GNU General Public License
# along with redmine_checklists. If not, see <http://www.gnu.org/licenses/>.
Rails.configuration.to_prepare do
require 'redmine_checklists/hooks/views_issues_hook'
require 'redmine_checklists/hooks/views_layouts_hook'
require 'redmine_checklists/hooks/controller_issues_hook'
require 'redmine_checklists/patches/issue_patch'
require 'redmine_checklists/patches/project_patch'
require 'redmine_checklists/patches/issues_controller_patch'
require 'redmine_checklists/patches/add_helpers_for_checklists_patch'
require 'redmine_checklists/patches/compatibility_patch'
require 'redmine_checklists/patches/issues_helper_patch'
require 'redmine_checklists/patches/compatibility/open_struct_patch'
require 'redmine_checklists/patches/compatibility/journal_patch'
end
module RedmineChecklists
def self.settings() Setting[:plugin_redmine_checklists].blank? ? {} : Setting[:plugin_redmine_checklists] end
end