Actualizar plugin Checklists a 3.1.18 light
This commit is contained in:
parent
a26f5567af
commit
24560c8598
55 changed files with 992 additions and 307 deletions
1
plugins/redmine_checklists/Gemfile
Normal file
1
plugins/redmine_checklists/Gemfile
Normal file
|
@ -0,0 +1 @@
|
|||
gem 'redmine_crm'
|
|
@ -1,7 +1,7 @@
|
|||
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
|
||||
# issue checklists management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2011-2017 RedmineUP
|
||||
# Copyright (C) 2011-2020 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_checklists is free software: you can redistribute it and/or modify
|
||||
|
@ -20,9 +20,9 @@
|
|||
class ChecklistsController < ApplicationController
|
||||
unloadable
|
||||
|
||||
before_filter :find_checklist_item, :except => [:index, :create]
|
||||
before_filter :find_issue_by_id, :only => [:index, :create]
|
||||
before_filter :authorize, :except => [:done]
|
||||
before_action :find_checklist_item, :except => [:index, :create]
|
||||
before_action :find_issue_by_id, :only => [:index, :create]
|
||||
before_action :authorize, :except => [:done]
|
||||
helper :issues
|
||||
|
||||
accept_api_auth :index, :update, :destroy, :create, :show
|
||||
|
@ -48,11 +48,13 @@ class ChecklistsController < ApplicationController
|
|||
end
|
||||
|
||||
def create
|
||||
@checklist_item = Checklist.new(params[:checklist])
|
||||
@checklist_item = Checklist.new
|
||||
@checklist_item.safe_attributes = params[:checklist]
|
||||
@checklist_item.issue = @issue
|
||||
respond_to do |format|
|
||||
format.api {
|
||||
if @checklist_item.save
|
||||
recalculate_issue_ratio(@checklist_item)
|
||||
render :action => 'show', :status => :created, :location => checklist_url(@checklist_item)
|
||||
else
|
||||
render_validation_errors(@checklist_item)
|
||||
|
@ -62,9 +64,11 @@ class ChecklistsController < ApplicationController
|
|||
end
|
||||
|
||||
def update
|
||||
@checklist_item.safe_attributes = params[:checklist]
|
||||
respond_to do |format|
|
||||
format.api {
|
||||
if @checklist_item.update_attributes(params[:checklist])
|
||||
if with_issue_journal { @checklist_item.save }
|
||||
recalculate_issue_ratio(@checklist_item)
|
||||
render_api_ok
|
||||
else
|
||||
render_validation_errors(@checklist_item)
|
||||
|
@ -75,12 +79,12 @@ class ChecklistsController < ApplicationController
|
|||
|
||||
def done
|
||||
(render_403; return false) unless User.current.allowed_to?(:done_checklists, @checklist_item.issue.project)
|
||||
@checklist_item.is_done = params[:is_done] == 'true'
|
||||
|
||||
if @checklist_item.save
|
||||
if (Setting.issue_done_ratio == "issue_field") && RedmineChecklists.settings["issue_done_ratio"].to_i > 0
|
||||
Checklist.recalc_issue_done_ratio(@checklist_item.issue.id)
|
||||
@checklist_item.issue.reload
|
||||
with_issue_journal do
|
||||
@checklist_item.is_done = params[:is_done] == 'true'
|
||||
if @checklist_item.save
|
||||
recalculate_issue_ratio(@checklist_item)
|
||||
true
|
||||
end
|
||||
end
|
||||
respond_to do |format|
|
||||
|
@ -104,4 +108,15 @@ class ChecklistsController < ApplicationController
|
|||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
|
||||
def with_issue_journal(&block)
|
||||
return unless yield
|
||||
end
|
||||
|
||||
def recalculate_issue_ratio(checklist_item)
|
||||
if (Setting.issue_done_ratio == 'issue_field') && RedmineChecklists.issue_done_ratio?
|
||||
Checklist.recalc_issue_done_ratio(checklist_item.issue.id)
|
||||
checklist_item.issue.reload
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
|
||||
# issue checklists management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2011-2017 RedmineUP
|
||||
# Copyright (C) 2011-2020 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_checklists is free software: you can redistribute it and/or modify
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
|
||||
# issue checklists management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2011-2017 RedmineUP
|
||||
# Copyright (C) 2011-2020 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_checklists is free software: you can redistribute it and/or modify
|
||||
|
@ -22,10 +22,9 @@ class Checklist < ActiveRecord::Base
|
|||
include Redmine::SafeAttributes
|
||||
belongs_to :issue
|
||||
belongs_to :author, :class_name => "User", :foreign_key => "author_id"
|
||||
has_one :comment, :as => :commented, :dependent => :delete
|
||||
if ActiveRecord::VERSION::MAJOR >= 4
|
||||
attr_protected :id
|
||||
end
|
||||
|
||||
attr_protected :id if ActiveRecord::VERSION::MAJOR <= 4
|
||||
|
||||
acts_as_event :datetime => :created_at,
|
||||
:url => Proc.new {|o| {:controller => 'issues', :action => 'show', :id => o.issue_id}},
|
||||
:type => 'issue issue-closed',
|
||||
|
@ -51,17 +50,17 @@ class Checklist < ActiveRecord::Base
|
|||
:order_column => "#{table_name}.id"
|
||||
end
|
||||
|
||||
acts_as_list
|
||||
rcrm_acts_as_list
|
||||
|
||||
validates_presence_of :subject
|
||||
validates_length_of :subject, :maximum => 512
|
||||
validates_length_of :subject, maximum: 512
|
||||
validates_presence_of :position
|
||||
validates_numericality_of :position
|
||||
|
||||
def self.recalc_issue_done_ratio(issue_id)
|
||||
issue = Issue.find(issue_id)
|
||||
return false if (Setting.issue_done_ratio != "issue_field") || RedmineChecklists.settings["issue_done_ratio"].to_i < 1 || issue.checklists.empty?
|
||||
done_checklist = issue.checklists.map{|c| c.is_done ? 1 : 0}
|
||||
return false if (Setting.issue_done_ratio != 'issue_field') || !RedmineChecklists.issue_done_ratio? || issue.checklists.reject(&:is_section).empty?
|
||||
done_checklist = issue.checklists.reject(&:is_section).map { |c| c.is_done ? 1 : 0 }
|
||||
done_ratio = (done_checklist.count(1) * 10) / done_checklist.count * 10
|
||||
issue.update_attribute(:done_ratio, done_ratio)
|
||||
end
|
||||
|
@ -71,7 +70,7 @@ class Checklist < ActiveRecord::Base
|
|||
(detail.value.is_a?(String) && detail.value.match(/^\[[ |x]\] .+$/).present?)
|
||||
end
|
||||
|
||||
safe_attributes 'subject', 'position', 'issue_id', 'is_done'
|
||||
safe_attributes 'subject', 'position', 'issue_id', 'is_done', 'is_section'
|
||||
|
||||
def editable_by?(usr = User.current)
|
||||
usr && (usr.allowed_to?(:edit_checklists, project) || (author == usr && usr.allowed_to?(:edit_own_checklists, project)))
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
|
||||
# issue checklists management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2011-2017 RedmineUP
|
||||
# Copyright (C) 2011-2020 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_checklists is free software: you can redistribute it and/or modify
|
||||
|
@ -19,27 +19,24 @@
|
|||
|
||||
class JournalChecklistHistory
|
||||
def self.can_fixup?(journal_details)
|
||||
unless journal_details.journal
|
||||
return false
|
||||
end
|
||||
return false if journal_details.journal.nil?
|
||||
|
||||
issue = journal_details.journal.journalized
|
||||
unless issue.is_a?(Issue)
|
||||
return false
|
||||
end
|
||||
return false unless issue.is_a?(Issue)
|
||||
|
||||
prev_journal_scope = issue.journals.order('id DESC')
|
||||
prev_journal_scope = prev_journal_scope.where('id <> ?', journal_details.journal_id) if journal_details.journal_id
|
||||
prev_journal = prev_journal_scope.first
|
||||
unless prev_journal
|
||||
return false
|
||||
end
|
||||
return false unless prev_journal
|
||||
|
||||
return false if prev_journal.user_id != journal_details.journal.user_id
|
||||
return false if Time.zone.now > prev_journal.created_on + 1.minute
|
||||
|
||||
prev_journal.details.all?{ |x| x.prop_key == 'checklist'} &&
|
||||
journal_details.journal.details.all?{ |x| x.prop_key == 'checklist'} &&
|
||||
prev_journal.details.all? { |x| x.prop_key == 'checklist' } &&
|
||||
journal_details.journal.details.all? { |x| x.prop_key == 'checklist' } &&
|
||||
journal_details.journal.notes.blank? &&
|
||||
prev_journal.notes.blank? &&
|
||||
prev_journal.details.select{ |x| x.prop_key == 'checklist' }.size == 1
|
||||
prev_journal.details.select { |x| x.prop_key == 'checklist' }.size == 1
|
||||
end
|
||||
|
||||
def self.fixup(journal_details)
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
<li id="checklist_item_<%= checklist_item.id %>" <%= "class=is-done-checklist-item" if checklist_item.is_done %> >
|
||||
<%= check_box_tag 'checklist_item', "", checklist_item.is_done,
|
||||
:disabled => !User.current.allowed_to?(:done_checklists, checklist_item.issue.project) && !User.current.allowed_to?(:edit_checklists, checklist_item.issue.project),
|
||||
:data_url => url_for( {:controller => "checklists", :action => "done", :id => checklist_item.id} ), :class => 'checklist-checkbox'
|
||||
%>
|
||||
<li id="checklist_item_<%= checklist_item.id %>" class="<%= 'is-done-checklist-item' if checklist_item.is_done %> <%= 'checklist-section' if checklist_item.is_section %>">
|
||||
<% unless checklist_item.is_section %>
|
||||
<%= check_box_tag 'checklist_item', '', checklist_item.is_done,
|
||||
disabled: !User.current.allowed_to?(:done_checklists, checklist_item.issue.project) && !User.current.allowed_to?(:edit_checklists, checklist_item.issue.project),
|
||||
data_url: url_for({ controller: 'checklists', action: 'done', id: checklist_item.id }),
|
||||
class: 'checklist-checkbox',
|
||||
id: "checklist-checkbox-#{checklist_item.id}"
|
||||
%>
|
||||
<% end %>
|
||||
<%= textilizable(checklist_item, :subject).gsub(/<\/?(p|h\d+|li|ul)>/, '').strip.html_safe %>
|
||||
|
||||
</li>
|
||||
|
|
|
@ -2,3 +2,16 @@ $("#checklist_item_<%= @checklist_item.id %>").toggleClass('is-done-checklist-it
|
|||
$('#checklist_form .checklist-item#<%= @checklist_item.id %> input[type=checkbox]').trigger('click');
|
||||
$('.issue .attributes table.progress').parent().html('<%= j(progress_bar(@checklist_item.issue.done_ratio, :width => '80px', :legend => "#{@checklist_item.issue.done_ratio}%")) %>');
|
||||
$('#issue_done_ratio').val('<%= @checklist_item.issue.done_ratio %>');
|
||||
|
||||
var checkedCheckboxes = $('.checklist-checkbox:checkbox:checked');
|
||||
|
||||
if(localStorage.getItem("hide_closed_checklists") === '0' && checkedCheckboxes.length > 0){
|
||||
$("#checklist_item_<%= @checklist_item.id %>").fadeOut(1000).hide(15);
|
||||
$('#switch_link').text('<%= l("label_checklist_show_closed") %>' + '(' + checkedCheckboxes.length + ')');
|
||||
}
|
||||
if(checkedCheckboxes.length < 1 && localStorage.getItem("hide_closed_checklists") === '1'){
|
||||
$('#switch_link').hide();
|
||||
}
|
||||
if(checkedCheckboxes.length > 0){
|
||||
$('#switch_link').show();
|
||||
}
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
<% if !@issue.blank? && @issue.checklists.any? && User.current.allowed_to?(:view_checklists, @project) %>
|
||||
<hr />
|
||||
<div id="checklist">
|
||||
|
||||
<div class="contextual">
|
||||
<%= link_to l("label_checklist_hide_closed"), '#', id: 'switch_link' %>
|
||||
</div>
|
||||
<p><strong><%=l(:label_checklist_plural)%></strong></p>
|
||||
|
||||
<ul id="checklist_items">
|
||||
|
@ -11,6 +13,7 @@
|
|||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
<%= javascript_tag do %>
|
||||
new Redmine.ChecklistToggle('<%= l("label_checklist_show_closed") %>', '<%= l("label_checklist_hide_closed") %>');
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
|
|
@ -1,21 +1,26 @@
|
|||
<span class="checklist-item <%= new_or_show(f) %>" id = "<%=f.object.id%>">
|
||||
<span class = "checklist-show-only checklist-checkbox"><%= f.check_box :is_done %></span>
|
||||
<span class = "checklist-show checklist-subject <%= done_css(f) %>">
|
||||
<%= f.object.subject %>
|
||||
<span class="checklist-item <%= new_or_show(f) %> <%= 'checklist-section' if f.object.is_section %>" id="<%= f.object.id %>">
|
||||
<% unless f.object.is_section %>
|
||||
<span class="checklist-show-only checklist-checkbox"><%= f.check_box :is_done %></span>
|
||||
<% end %>
|
||||
|
||||
<span class="checklist-show checklist-subject <%= done_css(f) %>">
|
||||
<%= textilizable(f.object, :subject).gsub(/<\/?(p|h\d+|li|ul)>/, '').strip.html_safe %>
|
||||
</span>
|
||||
<span class = "checklist-edit checklist-new checklist-edit-box">
|
||||
<%= text_field_tag nil, f.object.subject, :class => 'edit-box'%>
|
||||
<%= f.hidden_field :subject, :class => 'checklist-subject-hidden' %>
|
||||
|
||||
<span class="checklist-edit checklist-new checklist-edit-box">
|
||||
<%= text_field_tag nil, f.object.subject, class: 'edit-box' %>
|
||||
<%= f.hidden_field :subject, class: 'checklist-subject-hidden' %>
|
||||
</span>
|
||||
<span class= "checklist-edit-only checklist-edit-save-button"><%= submit_tag l(:button_save), :type => "button", :class => "item item-save small"%> </span>
|
||||
<span class= "checklist-edit-only checklist-edit-reset-button"><% concat l(:button_cancel)
|
||||
%> </span>
|
||||
<span class = "checklist-show-only checklist-remove"><%= link_to_remove_checklist_fields "", f,
|
||||
:class => "icon icon-del" %></span>
|
||||
<%= f.hidden_field :position, :class => 'checklist-item-position' %>
|
||||
<%= f.hidden_field :id, :class => 'checklist-item-id' %>
|
||||
<span class = "icon icon-add checklist-new-only save-new-by-button"></span>
|
||||
|
||||
<span class="checklist-edit-only checklist-edit-save-button"><%= submit_tag l(:button_save), type: 'button', class: 'item item-save small' %> </span>
|
||||
<span class="checklist-edit-only checklist-edit-reset-button"><% concat l(:button_cancel) %> </span>
|
||||
<span class="checklist-show-only checklist-remove"><%= link_to_remove_checklist_fields "", f, class: 'icon icon-del' %></span>
|
||||
|
||||
<%= f.hidden_field :position, class: 'checklist-item-position' %>
|
||||
<%= f.hidden_field :is_section, class: 'checklist-item-is_section' %>
|
||||
<%= f.hidden_field :id, class: 'checklist-item-id' %>
|
||||
|
||||
<span class="icon icon-add checklist-new-only save-new-by-button"></span>
|
||||
|
||||
<br>
|
||||
</span>
|
||||
|
||||
|
|
|
@ -5,3 +5,9 @@
|
|||
<%= check_box_tag 'settings[issue_done_ratio]', 1, @settings["issue_done_ratio"].to_i > 0 %>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<p>
|
||||
<label for="settings_block_issue_closing"><%= l(:label_checklist_block_issue_closing) %></label>
|
||||
<%= hidden_field_tag 'settings[block_issue_closing]', 0, :id => nil %>
|
||||
<%= check_box_tag 'settings[block_issue_closing]', 1, @settings["block_issue_closing"].to_i > 0 %>
|
||||
</p>
|
||||
|
|
|
@ -110,15 +110,11 @@ Redmine.Checklist = $.klass({
|
|||
event.returnValue = false
|
||||
},
|
||||
|
||||
addChecklistFields: function(templateDiv) {
|
||||
addChecklistFields: function() {
|
||||
var new_id = new Date().getTime();
|
||||
var regexp = new RegExp("new_checklist", "g");
|
||||
if (templateDiv) {
|
||||
appended = $(this.content.replace(regexp, new_id)).insertBefore(templateDiv)
|
||||
} else {
|
||||
appended = $(this.content.replace(regexp, new_id)).appendTo(this.root)
|
||||
}
|
||||
appended.find('.edit-box').focus()
|
||||
appended = $(this.content.replace(regexp, new_id)).appendTo(this.root);
|
||||
appended.find('.edit-box').focus();
|
||||
},
|
||||
|
||||
findSpan: function(event) {
|
||||
|
@ -129,13 +125,16 @@ Redmine.Checklist = $.klass({
|
|||
return elem.prevAll('span.checklist-item.new')
|
||||
},
|
||||
|
||||
transformItem: function(event, elem, valueToSet) {
|
||||
transformItem: function(event, elem, valueToSet, isSection) {
|
||||
var checklistItem;
|
||||
if (event) {
|
||||
checklistItem = this.findSpan(event)
|
||||
} else {
|
||||
} else if (elem) {
|
||||
checklistItem = this.findSpanBefore(elem)
|
||||
} else {
|
||||
checklistItem = this.root.find('span.checklist-item.new')
|
||||
}
|
||||
|
||||
var val;
|
||||
if (valueToSet) {
|
||||
val = valueToSet
|
||||
|
@ -143,11 +142,17 @@ Redmine.Checklist = $.klass({
|
|||
} else {
|
||||
val = checklistItem.find('input.edit-box').val()
|
||||
}
|
||||
|
||||
checklistItem.find('.checklist-subject').text(val)
|
||||
checklistItem.find('.checklist-subject-hidden').val(val)
|
||||
checklistItem.removeClass('edit')
|
||||
checklistItem.removeClass('new')
|
||||
checklistItem.addClass('show')
|
||||
|
||||
if (isSection) {
|
||||
checklistItem.addClass('checklist-section');
|
||||
checklistItem.children('.checklist-item-is_section').val(true);
|
||||
}
|
||||
},
|
||||
|
||||
resetItem: function(item) {
|
||||
|
@ -157,12 +162,9 @@ Redmine.Checklist = $.klass({
|
|||
},
|
||||
|
||||
addChecklistItem: function(event) {
|
||||
this.preventEvent(event)
|
||||
this.transformItem(event)
|
||||
if ($('.template-wrapper').length)
|
||||
this.addChecklistFields($('.template-wrapper'))
|
||||
else
|
||||
this.addChecklistFields()
|
||||
this.preventEvent(event);
|
||||
this.transformItem(event);
|
||||
this.addChecklistFields();
|
||||
},
|
||||
|
||||
canSave: function(span) {
|
||||
|
@ -193,6 +195,57 @@ Redmine.Checklist = $.klass({
|
|||
}, this))
|
||||
},
|
||||
|
||||
onClickAddChecklistItemMenuButton: function() {
|
||||
$('#checklist-menu .add-checklist-item').on('click', $.proxy(function(event) {
|
||||
this.preventEvent(event);
|
||||
var span = $('#checklist_form_items > span.checklist-item.new');
|
||||
if (this.canSave(span)) {
|
||||
this.transformItem();
|
||||
this.addChecklistFields();
|
||||
this.$plusButtonMenu.hide();
|
||||
}
|
||||
}, this))
|
||||
},
|
||||
|
||||
onClickNewSectionMenuButton: function() {
|
||||
$('#checklist-menu .add-checklist-section').on('click', $.proxy(function(event) {
|
||||
this.preventEvent(event);
|
||||
var span = $('#checklist_form_items > span.checklist-item.new');
|
||||
if (this.canSave(span)) {
|
||||
this.transformItem(null, null, null, true);
|
||||
this.addChecklistFields();
|
||||
this.$plusButtonMenu.hide();
|
||||
}
|
||||
}, this))
|
||||
},
|
||||
|
||||
onMouseEnterLeavePlusButton: function() {
|
||||
var hideMenuTimer;
|
||||
var $menu = this.$plusButtonMenu;
|
||||
|
||||
this.root.on('mouseenter', '.save-new-by-button', function() {
|
||||
var $plusButton = $(this);
|
||||
var position = $plusButton.position();
|
||||
$menu.css('left', (position.left + 'px'));
|
||||
$menu.css('top', (position.top + $plusButton.height() + 'px'));
|
||||
$menu.show();
|
||||
});
|
||||
|
||||
this.root.on('mouseleave', '.save-new-by-button', function() {
|
||||
hideMenuTimer = setTimeout(function() {
|
||||
$menu.hide();
|
||||
}, 500);
|
||||
});
|
||||
|
||||
$('#checklist-menu').on('mouseenter', function() {
|
||||
clearTimeout(hideMenuTimer);
|
||||
});
|
||||
|
||||
$('#checklist-menu').on('mouseleave', function() {
|
||||
$menu.hide();
|
||||
});
|
||||
},
|
||||
|
||||
onIssueFormSubmitRemoveEmptyChecklistItems: function() {
|
||||
$('body').on('submit', '#issue-form', function(){
|
||||
$('.checklist-subject-hidden').each(function(i, elem) {
|
||||
|
@ -206,16 +259,19 @@ Redmine.Checklist = $.klass({
|
|||
|
||||
onChecklistRemove: function() {
|
||||
this.root.on('click', '.checklist-remove a', $.proxy(function(event){
|
||||
this.preventEvent(event)
|
||||
removed = this.findSpan(event)
|
||||
removed.find('.checklist-remove input[type=hidden]').val('1')
|
||||
removed.fadeOut(200)
|
||||
}, this))
|
||||
this.preventEvent(event);
|
||||
var itemToRemove = this.findSpan(event);
|
||||
var checkbox = itemToRemove.find(".checklist-remove input[type=hidden]");
|
||||
|
||||
if (checkbox.val() === "false") {
|
||||
checkbox.val("1");
|
||||
itemToRemove.fadeOut(200);
|
||||
}
|
||||
}, this));
|
||||
},
|
||||
|
||||
makeChecklistsSortable: function() {
|
||||
$('#checklist_form_items').sortable({
|
||||
revert: true,
|
||||
items: '.checklist-item.show',
|
||||
helper: "clone",
|
||||
stop: function (event, ui) {
|
||||
|
@ -265,13 +321,33 @@ Redmine.Checklist = $.klass({
|
|||
},
|
||||
|
||||
onChangeCheckbox: function(){
|
||||
this.root.on('change', 'input.checklist-checkbox', $.proxy(function(event){
|
||||
this.root.on('change', 'input.checklist-checkbox', $.proxy(function(event) {
|
||||
this.darkenCompletedSections();
|
||||
checkbox = $(event.target)
|
||||
url = checkbox.attr('data_url')
|
||||
$.ajax({type: "PUT", url: url, data: { is_done: checkbox.prop('checked') }, dataType: 'script'})
|
||||
}, this))
|
||||
},
|
||||
|
||||
darkenCompletedSections: function() {
|
||||
var isCompletedSection = true;
|
||||
var reversedChecklistItems = $('#checklist_items li').get().reverse();
|
||||
|
||||
$(reversedChecklistItems).each(function(index, element) {
|
||||
var $element = $(element);
|
||||
if ($element.hasClass('checklist-section')) {
|
||||
if (isCompletedSection) {
|
||||
$element.addClass('completed-section')
|
||||
} else {
|
||||
$element.removeClass('completed-section')
|
||||
}
|
||||
isCompletedSection = true;
|
||||
} else {
|
||||
isCompletedSection = isCompletedSection && $element.children('.checklist-checkbox').is(':checked')
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
enableUniquenessValidation: function() {
|
||||
this.root.on('keyup', 'input.edit-box', $.proxy(function(event) {
|
||||
value = $(event.target).val()
|
||||
|
@ -303,39 +379,39 @@ Redmine.Checklist = $.klass({
|
|||
},
|
||||
|
||||
assignTemplateSelectedEvent: function() {
|
||||
var item;
|
||||
this.root.on('change', '#checklist_template', $.proxy(function(){
|
||||
value = $('#checklist_template').val()
|
||||
selected = $('#checklist_template option[value='+value+']').data('template-items')
|
||||
items = selected.split(/\n/)
|
||||
for(i = 0; i<items.length; i++)
|
||||
{
|
||||
item = items[i]
|
||||
if (!this.hasAlreadyChecklistWithName(item))
|
||||
{
|
||||
this.transformItem(null, $('#checklist_template'), item)
|
||||
this.addChecklistFields($('#template-link').closest('span'))
|
||||
this.$plusButtonMenu.on('click', 'li a.checklist-template', $.proxy(function(event) {
|
||||
this.preventEvent(event);
|
||||
items = $(event.target).data('template-items').split(/\n/);
|
||||
for(var i = 0; i < items.length; i++) {
|
||||
var item = items[i];
|
||||
var isSection = item.slice(0, 2) === '--';
|
||||
if (isSection) { item = item.slice(2) }
|
||||
if (!this.hasAlreadyChecklistWithName(item)) {
|
||||
this.transformItem(null, null, item, isSection);
|
||||
this.addChecklistFields();
|
||||
}
|
||||
}
|
||||
$('#checklist_template').val('')
|
||||
$('#template-link').show()
|
||||
$('#checklist_template').hide()
|
||||
|
||||
}, this))
|
||||
},
|
||||
|
||||
clickSelectTemplateLink: function() {
|
||||
this.root.on('click', '#template-link', function(){
|
||||
$('#template-link').hide()
|
||||
$('#checklist_template').show()
|
||||
})
|
||||
},
|
||||
|
||||
init: function(element) {
|
||||
this.root = element
|
||||
this.content = element.data('checklist-fields')
|
||||
this.onEnterInNewChecklistItemForm()
|
||||
this.onClickPlusInNewChecklistItem()
|
||||
|
||||
if (this.content) {
|
||||
this.$plusButtonMenu = $('#checklist-menu').menu();
|
||||
if (this.$plusButtonMenu.length > 0) {
|
||||
this.onMouseEnterLeavePlusButton();
|
||||
this.onClickAddChecklistItemMenuButton();
|
||||
this.assignTemplateSelectedEvent();
|
||||
this.onClickNewSectionMenuButton();
|
||||
}
|
||||
} else {
|
||||
this.darkenCompletedSections()
|
||||
}
|
||||
|
||||
this.onIssueFormSubmitRemoveEmptyChecklistItems()
|
||||
this.onChecklistRemove()
|
||||
this.makeChecklistsSortable()
|
||||
|
@ -343,12 +419,59 @@ Redmine.Checklist = $.klass({
|
|||
this.onCheckboxChanged()
|
||||
this.onChangeCheckbox()
|
||||
this.enableUniquenessValidation()
|
||||
this.assignTemplateSelectedEvent()
|
||||
this.clickSelectTemplateLink()
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
$.fn.checklist = function(element){
|
||||
new Redmine.Checklist(this);
|
||||
}
|
||||
};
|
||||
|
||||
Redmine.ChecklistToggle = $.klass({
|
||||
manageToggling: function (t_val) {
|
||||
var checkedCheckboxes = $('.checklist-checkbox:checkbox:checked');
|
||||
|
||||
if(localStorage.getItem("hide_closed_checklists") === t_val){
|
||||
$($(checkedCheckboxes).closest('li')).hide();
|
||||
$(this.switch_link).text(this.show_text + '(' + checkedCheckboxes.length + ')');
|
||||
} else {
|
||||
$($(checkedCheckboxes).closest('li')).show();
|
||||
$(this.switch_link).text(this.hide_text);
|
||||
}
|
||||
},
|
||||
switch_link_click: function(){
|
||||
var th = $(this)[0];
|
||||
this.switch_link.click(function (e) {
|
||||
e.preventDefault();
|
||||
th.manageToggling("1");
|
||||
var setVal = (localStorage.getItem("hide_closed_checklists") === "1") ? "0" : "1";
|
||||
localStorage.setItem("hide_closed_checklists", setVal);
|
||||
});
|
||||
},
|
||||
hide_switch_link: function(){
|
||||
if($('.checklist-checkbox:checkbox:checked').length < 1){
|
||||
this.switch_link.hide();
|
||||
}
|
||||
},
|
||||
init: function(show_text, hide_text) {
|
||||
this.show_text = show_text;
|
||||
this.hide_text = hide_text;
|
||||
this.switch_link = $('#switch_link');
|
||||
this.manageToggling("0");
|
||||
this.switch_link_click();
|
||||
this.hide_switch_link();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
$(document).ready(function () {
|
||||
if (typeof(contextMenuCheckSelectionBox) === 'function') {
|
||||
var originContextMenuCheckSelectionBox = contextMenuCheckSelectionBox;
|
||||
contextMenuCheckSelectionBox = function (tr, checked) {
|
||||
var $td = tr.find('td.checklist_relations');
|
||||
var $checklist = $td.find('.checklist').detach();
|
||||
originContextMenuCheckSelectionBox(tr, checked);
|
||||
$checklist.appendTo($td);
|
||||
};
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
#checklist_form_items input[type="checkbox"],
|
||||
#checklist_items input[type="checkbox"] {
|
||||
height: initial;
|
||||
}
|
||||
|
||||
div#checklist ul {
|
||||
list-style: none;
|
||||
|
@ -10,6 +14,8 @@ div#checklist li {
|
|||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.checklist-checkbox {height: inherit}
|
||||
|
||||
#checklist li:hover a.delete {opacity: 1;}
|
||||
|
||||
#checklist a.delete {opacity: 0.4;}
|
||||
|
@ -74,4 +80,65 @@ span.checklist-item.edit .checklist-show-only {
|
|||
div#checklist ol {
|
||||
display: inline-block;
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.checklist-section {
|
||||
padding-top: 10px;
|
||||
font-weight: bold;
|
||||
border-bottom-width: 1px;
|
||||
border-bottom-style: solid;
|
||||
border-bottom-color: #eee;
|
||||
}
|
||||
|
||||
.checklist-item.checklist-section > .checklist-checkbox { display: none; }
|
||||
|
||||
#checklist_items li.checklist-section {
|
||||
padding-bottom: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.completed-section { color: #999; }
|
||||
|
||||
.save-new-by-button { cursor: pointer; }
|
||||
|
||||
table.list td.checklist_relations { text-align: left }
|
||||
|
||||
/* ========================================================================= */
|
||||
/* Checklist context menu */
|
||||
/* ========================================================================= */
|
||||
|
||||
#checklist-menu ul, #checklist-menu li, #checklist-menu a {
|
||||
display:block;
|
||||
margin:0;
|
||||
padding:0;
|
||||
border:0;
|
||||
}
|
||||
|
||||
#checklist-menu {
|
||||
display: none;
|
||||
position: absolute;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
#checklist-menu, #checklist-menu ul {
|
||||
width: 150px;
|
||||
border: 1px solid #ccc;
|
||||
background: white;
|
||||
list-style: none;
|
||||
padding: 2px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
#checklist-menu li {
|
||||
position: relative;
|
||||
padding: 1px;
|
||||
border: 1px solid white;
|
||||
}
|
||||
|
||||
#checklist-menu a {
|
||||
text-decoration: none !important;
|
||||
padding: 2px 0px 2px 20px;
|
||||
}
|
||||
|
||||
#checklist-menu a:hover { color:#2A5685; }
|
||||
#checklist-menu li:hover { border:1px solid #628db6; background-color:#eef5fd; border-radius:3px; }
|
||||
|
|
|
@ -25,5 +25,12 @@ de:
|
|||
label_checklist_changed_to: zu
|
||||
label_checklist_added: hinzugefügt
|
||||
label_checklist_done: als Erledigt markiert
|
||||
label_checklist_undone: als Nicht Erledigt markiert
|
||||
label_checklist_updated: Checklisten-Eintrag editiert
|
||||
label_checklist_undone: als Nicht erledigt markiert
|
||||
label_checklist_updated: Checklisten-Eintrag editiert
|
||||
label_checklist_status: Checklisten-Status
|
||||
label_checklist_status_done: Erledigt
|
||||
label_checklist_status_undone: Nicht erledigt
|
||||
label_checklist_is_default: Standard
|
||||
field_is_for_tracker: Tracker
|
||||
label_checklists_must_be_completed: "Alle Checklisten-Einträge eines Tickets müssen vor dem Schließen erledigt werden."
|
||||
label_checklist_block_issue_closing: "Schließen des Tickets blockieren"
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
# English strings go here for Rails i18n
|
||||
en:
|
||||
activerecord:
|
||||
attributes:
|
||||
checklists:
|
||||
subject: Checklist subject
|
||||
label_checklist_plural: Checklist
|
||||
field_checklist: Checklist
|
||||
label_checklist_save_log: Save changes to issue log
|
||||
|
@ -15,10 +19,12 @@ en:
|
|||
field_template_items: Template items
|
||||
label_checklist_template: Checklist template
|
||||
label_add_checklists_from_template: Add from template
|
||||
label_checklists_from_template: From template
|
||||
label_select_template: "-- Select template --"
|
||||
label_checklist_category_not_specified: "-- Not specified --"
|
||||
label_checklists_description: 'Multiple values allowed (one line for each value)'
|
||||
label_checklist_item: Checklist item
|
||||
label_checklist_section: Checklist section
|
||||
label_checklist_deleted: deleted
|
||||
label_checklist_changed_from: changed from
|
||||
label_checklist_changed_to: to
|
||||
|
@ -29,6 +35,10 @@ en:
|
|||
label_checklist_status: Checklist status
|
||||
label_checklist_status_done: Done
|
||||
label_checklist_status_undone: Undone
|
||||
label_checklist_status: Checklist status
|
||||
label_checklist_is_default: Default
|
||||
field_is_for_tracker: Tracker
|
||||
label_checklists_must_be_completed: All checklists of an issue must be done before closing
|
||||
label_checklist_block_issue_closing: Block issue closing
|
||||
label_checklist_show_closed: Show closed
|
||||
label_checklist_hide_closed: Hide closed
|
||||
label_checklist_new_section: New section
|
||||
|
|
|
@ -2,3 +2,8 @@
|
|||
fr:
|
||||
label_checklist_plural: Liste de Tâches
|
||||
field_checklist: Tâche
|
||||
label_checklist_templates: Template de checklists
|
||||
label_checklist_new_checklist_template: Ajouter un template
|
||||
field_is_for_tracker:
|
||||
label_checklist_is_default: Checklist par d faut
|
||||
field_template_items: Eléments
|
||||
|
|
45
plugins/redmine_checklists/config/locales/it.yml
Normal file
45
plugins/redmine_checklists/config/locales/it.yml
Normal file
|
@ -0,0 +1,45 @@
|
|||
# encoding: utf-8
|
||||
# Italian strings go here for Rails i18n
|
||||
it:
|
||||
activerecord:
|
||||
attributes:
|
||||
checklists:
|
||||
subject: Checklist soggetto
|
||||
label_checklist_plural: Checklist
|
||||
field_checklist: Checklist
|
||||
label_checklist_save_log: Salva le modifiche nel log delle segnalazioni
|
||||
label_checklist_done_ratio: Imposta ratio checklist segnalazioni completate
|
||||
permission_view_checklists: Visualizza la checklist
|
||||
permission_done_checklists: Elementi checklist completati
|
||||
permission_edit_checklists: Modifica elementi checklist
|
||||
label_checklist_template_category_plural: Categorie di modelli
|
||||
label_checklist_template_category_new: Nuova categoria
|
||||
field_checklist_template_category: Categoria
|
||||
label_checklist_templates: Modelli di checklist
|
||||
label_checklist_new_checklist_template: Nuovo modello di checklist
|
||||
field_template_items: Elementi del modello
|
||||
label_checklist_template: Modello di checklist
|
||||
label_add_checklists_from_template: Aggiungi dal modello
|
||||
label_checklists_from_template: Dal modello
|
||||
label_select_template: "- Seleziona modello -"
|
||||
label_checklist_category_not_specified: "-- Non specificato --"
|
||||
label_checklists_description: "Sono consentiti più valori (una riga per ciascun valore)"
|
||||
label_checklist_item: Elemento della checklist
|
||||
label_checklist_section: Sezione checklist
|
||||
label_checklist_deleted: Eliminato
|
||||
label_checklist_changed_from: Modificato da
|
||||
label_checklist_changed_to: a
|
||||
label_checklist_added: aggiunto
|
||||
label_checklist_done: Impostato su Completato
|
||||
label_checklist_undone: Impostato su Non completato
|
||||
label_checklist_updated: Elemento della checklist aggiornato
|
||||
label_checklist_status: Stato della checklist
|
||||
label_checklist_status_done: Completato
|
||||
label_checklist_status_undone: Non completato
|
||||
label_checklist_is_default: Predefinito
|
||||
field_is_for_tracker: Tracker
|
||||
label_checklists_must_be_completed: Tutte le liste di controllo di una segnalazione devono essere eseguite prima della chiusura
|
||||
label_checklist_block_issue_closing: Blocca segnalazione in chiusura
|
||||
label_checklist_show_closed: Mostra completati
|
||||
label_checklist_hide_closed: Nascondi completati
|
||||
label_checklist_new_section: Nuova sezione
|
|
@ -1,5 +1,9 @@
|
|||
# encoding: utf-8
|
||||
ru:
|
||||
activerecord:
|
||||
attributes:
|
||||
checklists:
|
||||
subject: Заголовок чеклиста
|
||||
label_checklist_plural: Чеклист
|
||||
field_checklist: Чеклист
|
||||
label_checklist_save_log: Сохранять изменения в истории
|
||||
|
@ -15,10 +19,12 @@ ru:
|
|||
field_template_items: Элементы шаблона
|
||||
label_checklist_template: Шаблон чеклистов
|
||||
label_add_checklists_from_template: Добавить из шаблона
|
||||
label_checklists_from_template: Из шаблона
|
||||
label_select_template: "-- Выберите шаблон --"
|
||||
label_checklist_category_not_specified: "-- Без категории --"
|
||||
label_checklists_description: 'Для ввода нескольких значений вводите по одному на строку'
|
||||
label_checklist_item: Пункт чеклиста
|
||||
label_checklist_section: Раздел чеклиста
|
||||
label_checklist_deleted: удалён
|
||||
label_checklist_changed_from: изменён с
|
||||
label_checklist_changed_to: на
|
||||
|
@ -31,3 +37,10 @@ ru:
|
|||
label_checklist_status_undone: Не выполнен
|
||||
label_checklist_is_default: По умолчанию
|
||||
field_is_for_tracker: Трекер
|
||||
label_checklist_show_closed: Показать закрытые
|
||||
label_checklist_hide_closed: Скрыть закрытые
|
||||
label_checklist_new_section: Новая секция
|
||||
label_checklist_block_issue_closing: Запретить закрытие заявки
|
||||
label_checklists: Чеклист
|
||||
label_checklists_must_be_completed: Чтобы заявка закрылась, должны быть выполнены все пункты чеклиста
|
||||
field_checklists: Чеклист
|
||||
|
|
32
plugins/redmine_checklists/config/locales/zh-TW.yml
Normal file
32
plugins/redmine_checklists/config/locales/zh-TW.yml
Normal file
|
@ -0,0 +1,32 @@
|
|||
# encoding: utf-8
|
||||
# Simplified Chinese strings go here for Rails i18n
|
||||
# Author: Steven.W
|
||||
# Based on file: en.yml
|
||||
|
||||
zh-TW:
|
||||
label_checklist_plural: Checklist
|
||||
field_checklist: Checklist
|
||||
label_checklist_save_log: 保存檢查清單變更到問題日誌
|
||||
label_checklist_done_ratio: 設置列表完成比率
|
||||
permission_view_checklists: 查看Checklist
|
||||
permission_done_checklists: 完成Checklist
|
||||
permission_edit_checklists: 編輯Checklist
|
||||
label_checklist_template_category_plural: 範本類別
|
||||
label_checklist_template_category_new: 新類別
|
||||
field_checklist_template_category: 類別
|
||||
label_checklist_templates: 檢查清單範本
|
||||
label_checklist_new_checklist_template: 新檢查清單範本
|
||||
field_template_items: 範本項
|
||||
label_checklist_template: 檢查清單範本
|
||||
label_add_checklists_from_template: 從範本新建
|
||||
label_select_template: "-- 選擇範本 --"
|
||||
label_checklist_category_not_specified: "-- 未指定 --"
|
||||
label_checklists_description: '允許多重值 (每一行的值)'
|
||||
label_checklist_item: Checklist item
|
||||
label_checklist_deleted: 刪除
|
||||
label_checklist_changed_from: 改變自
|
||||
label_checklist_changed_to: 到
|
||||
label_checklist_added: 添加
|
||||
label_checklist_done: 設置完成
|
||||
label_checklist_undone: 設置未完成
|
||||
label_checklist_updated: Checklist item編輯
|
|
@ -1,7 +1,7 @@
|
|||
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
|
||||
# issue checklists management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2011-2017 RedmineUP
|
||||
# Copyright (C) 2011-2020 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_checklists is free software: you can redistribute it and/or modify
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
|
||||
# issue checklists management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2011-2017 RedmineUP
|
||||
# Copyright (C) 2011-2020 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_checklists is free software: you can redistribute it and/or modify
|
||||
|
@ -17,7 +17,7 @@
|
|||
# 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 CreateChecklists < ActiveRecord::Migration
|
||||
class CreateChecklists < Rails.version < '5.1' ? ActiveRecord::Migration : ActiveRecord::Migration[4.2]
|
||||
|
||||
def self.up
|
||||
if ActiveRecord::Base.connection.table_exists? :issue_checklists
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
|
||||
# issue checklists management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2011-2017 RedmineUP
|
||||
# Copyright (C) 2011-2020 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_checklists is free software: you can redistribute it and/or modify
|
||||
|
@ -17,7 +17,7 @@
|
|||
# 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 AddTimeStampsToChecklists < ActiveRecord::Migration
|
||||
class AddTimeStampsToChecklists < Rails.version < '5.1' ? ActiveRecord::Migration : ActiveRecord::Migration[4.2]
|
||||
def change
|
||||
add_column :checklists, :created_at, :timestamp
|
||||
add_column :checklists, :updated_at, :timestamp
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
|
||||
# issue checklists management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2011-2017 RedmineUP
|
||||
# Copyright (C) 2011-2020 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_checklists is free software: you can redistribute it and/or modify
|
||||
|
@ -17,7 +17,7 @@
|
|||
# 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 CreateChecklistTemplateCategory < ActiveRecord::Migration
|
||||
class CreateChecklistTemplateCategory < Rails.version < '5.1' ? ActiveRecord::Migration : ActiveRecord::Migration[4.2]
|
||||
|
||||
def self.up
|
||||
create_table :checklist_template_categories do |t|
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
|
||||
# issue checklists management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2011-2017 RedmineUP
|
||||
# Copyright (C) 2011-2020 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_checklists is free software: you can redistribute it and/or modify
|
||||
|
@ -17,7 +17,7 @@
|
|||
# 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 CreateChecklistTemplates < ActiveRecord::Migration
|
||||
class CreateChecklistTemplates < Rails.version < '5.1' ? ActiveRecord::Migration : ActiveRecord::Migration[4.2]
|
||||
|
||||
def self.up
|
||||
create_table :checklist_templates do |t|
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
|
||||
# issue checklists management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2011-2017 RedmineUP
|
||||
# Copyright (C) 2011-2020 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_checklists is free software: you can redistribute it and/or modify
|
||||
|
@ -17,7 +17,7 @@
|
|||
# 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 ModifyChecklistSubjectLength < ActiveRecord::Migration
|
||||
class ModifyChecklistSubjectLength < Rails.version < '5.1' ? ActiveRecord::Migration : ActiveRecord::Migration[4.2]
|
||||
def self.up
|
||||
change_column :checklists, :subject, :string, :limit => 512
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
|
||||
# issue checklists management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2011-2017 RedmineUP
|
||||
# Copyright (C) 2011-2020 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_checklists is free software: you can redistribute it and/or modify
|
||||
|
@ -17,7 +17,7 @@
|
|||
# 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 AddFieldsToChecklistTemplate < ActiveRecord::Migration
|
||||
class AddFieldsToChecklistTemplate < Rails.version < '5.1' ? ActiveRecord::Migration : ActiveRecord::Migration[4.2]
|
||||
def self.up
|
||||
add_column :checklist_templates, :is_default, :boolean, :default => false
|
||||
add_column :checklist_templates, :tracker_id, :integer
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
|
||||
# issue checklists management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2011-2020 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 AddIsSectionToChecklists < (Rails.version < '5.1') ? ActiveRecord::Migration : ActiveRecord::Migration[4.2]
|
||||
def change
|
||||
add_column :checklists, :is_section, :boolean, default: false
|
||||
end
|
||||
end
|
|
@ -1,9 +1,61 @@
|
|||
== Redmine Checklists plugin changelog
|
||||
|
||||
Redmine Checklists plugin - managing issue checklists plugin for Redmine
|
||||
Copyright (C) 2011-2017 RedmineUP
|
||||
Copyright (C) 2011-2020 RedmineUP
|
||||
http://www.redmineup.com/
|
||||
|
||||
== 2020-08-17 v3.1.18
|
||||
|
||||
* Added italian locale
|
||||
* Updated zh-tw locale
|
||||
* Fixed size() method error
|
||||
* Fixed initial install error
|
||||
* Fixed checklist ration recalculate
|
||||
* Fixed display checklist element with Markdown syntax
|
||||
* Fixed done ratio recalculate on checklist API update
|
||||
* Fixed API call journalizing
|
||||
|
||||
== 2020-01-31 v3.1.17
|
||||
|
||||
* Redmine 4.1 compatibility fixes
|
||||
* Fixed view permission bug
|
||||
* Fixed template permissions bug
|
||||
* Fixed context menu conflicts
|
||||
* Fixed Agile support
|
||||
* Fixed checklist copy bug
|
||||
* Fixed locale bug
|
||||
* Fixed project copy bug
|
||||
|
||||
== 2019-04-29 v3.1.16
|
||||
|
||||
* Checklists sections
|
||||
|
||||
== 2019-04-15 v3.1.15
|
||||
|
||||
* Redmine 4.0.3 support
|
||||
* Added Hide link for closed items
|
||||
|
||||
== 2018-12-20 v3.1.14
|
||||
|
||||
* Hotfix for Redmine 4
|
||||
|
||||
== 2018-12-18 v3.1.13
|
||||
|
||||
* Redmine 4 saving issue fixes
|
||||
|
||||
== 2018-11-26 v3.1.12
|
||||
|
||||
* German translation update from Tobias Fischer
|
||||
* Fixed diferent authors changes bug
|
||||
* Fixed sortable animation bug
|
||||
|
||||
== 2018-03-23 v3.1.11
|
||||
|
||||
* Redmine 4 support
|
||||
* Setting for block issues with undone checklists
|
||||
* Fixed bug with default template
|
||||
* Fixed email notification bug
|
||||
|
||||
== 2017-10-12 v3.1.10
|
||||
|
||||
* Fixed email notification bug
|
||||
|
@ -29,10 +81,10 @@ http://www.redmineup.com/
|
|||
|
||||
* Redmine 3.4 support
|
||||
* New checklists filters for issues table
|
||||
* Save log by default
|
||||
* Save log by default
|
||||
* Chinese translation update
|
||||
* Polish translation update
|
||||
* Fixed bug with template editing
|
||||
* Fixed bug with template editing
|
||||
|
||||
== 2016-08-15 v3.1.5
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
|
||||
# issue checklists management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2011-2017 RedmineUP
|
||||
# Copyright (C) 2011-2020 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_checklists is free software: you can redistribute it and/or modify
|
||||
|
@ -20,7 +20,7 @@
|
|||
require 'redmine'
|
||||
require 'redmine_checklists/redmine_checklists'
|
||||
|
||||
CHECKLISTS_VERSION_NUMBER = '3.1.10'
|
||||
CHECKLISTS_VERSION_NUMBER = '3.1.18'.freeze
|
||||
CHECKLISTS_VERSION_TYPE = "Light version"
|
||||
|
||||
Redmine::Plugin.register :redmine_checklists do
|
||||
|
@ -31,7 +31,7 @@ Redmine::Plugin.register :redmine_checklists do
|
|||
url 'https://www.redmineup.com/pages/plugins/checklists'
|
||||
author_url 'mailto:support@redmineup.com'
|
||||
|
||||
requires_redmine :version_or_higher => '2.3'
|
||||
requires_redmine :version_or_higher => '2.6'
|
||||
|
||||
settings :default => {
|
||||
:save_log => true,
|
||||
|
@ -40,9 +40,9 @@ Redmine::Plugin.register :redmine_checklists do
|
|||
|
||||
Redmine::AccessControl.map do |map|
|
||||
map.project_module :issue_tracking do |map|
|
||||
map.permission :view_checklists, {:checklists => [:show, :index]}
|
||||
map.permission :done_checklists, {:checklists => :done}
|
||||
map.permission :edit_checklists, {:checklists => [:done, :create, :destroy, :update]}
|
||||
map.permission :view_checklists, { :checklists => [:show, :index] }
|
||||
map.permission :done_checklists, { :checklists => :done }
|
||||
map.permission :edit_checklists, { :checklists => [:done, :create, :destroy, :update] }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
|
||||
# issue checklists management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2011-2017 RedmineUP
|
||||
# Copyright (C) 2011-2020 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_checklists is free software: you can redistribute it and/or modify
|
||||
|
@ -22,7 +22,7 @@ module RedmineChecklists
|
|||
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
|
||||
if (Setting.issue_done_ratio == 'issue_field') && RedmineChecklists.issue_done_ratio?
|
||||
Checklist.recalc_issue_done_ratio(context[:issue].id)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
|
||||
# issue checklists management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2011-2017 RedmineUP
|
||||
# Copyright (C) 2011-2020 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_checklists is free software: you can redistribute it and/or modify
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
|
||||
# issue checklists management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2011-2017 RedmineUP
|
||||
# Copyright (C) 2011-2020 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_checklists is free software: you can redistribute it and/or modify
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
|
||||
# issue checklists management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2011-2017 RedmineUP
|
||||
# Copyright (C) 2011-2020 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_checklists is free software: you can redistribute it and/or modify
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
|
||||
# issue checklists management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2011-2017 RedmineUP
|
||||
# Copyright (C) 2011-2020 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_checklists is free software: you can redistribute it and/or modify
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
|
||||
# issue checklists management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2011-2020 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 ApplicationHelperPatch
|
||||
def self.included(base) # :nodoc:
|
||||
base.class_eval do
|
||||
unloadable # Send unloadable so it will not be unloaded in development
|
||||
|
||||
def stocked_reorder_link(object, name = nil, url = {}, method = :post)
|
||||
Redmine::VERSION.to_s > '3.3' ? reorder_handle(object, :param => name) : reorder_links(name, url, method)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
unless ApplicationHelper.included_modules.include?(RedmineChecklists::Patches::ApplicationHelperPatch)
|
||||
ApplicationHelper.send(:include, RedmineChecklists::Patches::ApplicationHelperPatch)
|
||||
end
|
|
@ -1,7 +1,7 @@
|
|||
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
|
||||
# issue checklists management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2011-2017 RedmineUP
|
||||
# Copyright (C) 2011-2020 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_checklists is free software: you can redistribute it and/or modify
|
||||
|
@ -17,13 +17,11 @@
|
|||
# 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
|
||||
|
@ -40,7 +38,7 @@ module RedmineChecklists
|
|||
(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
|
||||
deliver_checklist_notification
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -49,17 +47,24 @@ module RedmineChecklists
|
|||
end
|
||||
end
|
||||
|
||||
def checklist_email_nootification(journal)
|
||||
def deliver_checklist_notification
|
||||
if Redmine::VERSION.to_s >= '4.0'
|
||||
(notified_watchers | notified_users).each do |user|
|
||||
Mailer.issue_edit(user, self).deliver
|
||||
end
|
||||
else
|
||||
checklist_email_notification(self).deliver
|
||||
end
|
||||
end
|
||||
|
||||
def checklist_email_notification(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)
|
||||
Mailer.issue_edit(journal, journal.notified_users, journal.notified_watchers - journal.notified_users)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
|
||||
# issue checklists management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2011-2017 RedmineUP
|
||||
# Copyright (C) 2011-2020 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_checklists is free software: you can redistribute it and/or modify
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
|
||||
# issue checklists management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2011-2017 RedmineUP
|
||||
# Copyright (C) 2011-2020 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_checklists is free software: you can redistribute it and/or modify
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
|
||||
# issue checklists management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2011-2017 RedmineUP
|
||||
# Copyright (C) 2011-2020 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_checklists is free software: you can redistribute it and/or modify
|
||||
|
@ -21,41 +21,46 @@ 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_accessor :removed_checklist_ids
|
||||
attr_reader :copied_from
|
||||
|
||||
alias_method_chain :copy, :checklist
|
||||
alias_method :copy_without_checklist, :copy
|
||||
alias_method :copy, :copy_with_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
|
||||
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'
|
||||
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? }
|
||||
accepts_nested_attributes_for :checklists, :allow_destroy => true, :reject_if => proc { |attrs| attrs['subject'].blank? }
|
||||
|
||||
validate :block_issue_closing_if_checklists_unclosed
|
||||
|
||||
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
|
||||
:if => lambda { |issue, user| (user.allowed_to?(:done_checklists, issue.project) || user.allowed_to?(:edit_checklists, issue.project)) }
|
||||
end
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
def copy_checklists(arg)
|
||||
issue = arg.is_a?(Issue) ? arg : Issue.visible.find(arg)
|
||||
if issue
|
||||
issue.checklists.each do |checklist|
|
||||
Checklist.create(checklist.attributes.except('id', 'issue_id').merge(issue: self))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def copy_subtask_checklists
|
||||
return if !copy? || parent_id.nil? || checklists.any?
|
||||
return if !copy? || parent_id.nil? || checklists.reload.any?
|
||||
copy_checklists(@copied_from)
|
||||
end
|
||||
|
||||
|
@ -64,6 +69,23 @@ module RedmineChecklists
|
|||
copy.copy_checklists(self)
|
||||
copy
|
||||
end
|
||||
|
||||
def all_checklist_items_is_done?
|
||||
(checklists - checklists.where(id: removed_checklist_ids)).reject(&:is_section).all?(&:is_done)
|
||||
end
|
||||
|
||||
def need_to_block_issue_closing?
|
||||
RedmineChecklists.block_issue_closing? &&
|
||||
checklists.reject(&:is_section).any? &&
|
||||
status.is_closed? &&
|
||||
!all_checklist_items_is_done?
|
||||
end
|
||||
|
||||
def block_issue_closing_if_checklists_unclosed
|
||||
if need_to_block_issue_closing?
|
||||
errors.add(:checklists, l(:label_checklists_must_be_completed))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
|
||||
# issue checklists management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2011-2017 RedmineUP
|
||||
# Copyright (C) 2011-2020 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_checklists is free software: you can redistribute it and/or modify
|
||||
|
@ -32,6 +32,7 @@ module RedmineChecklists
|
|||
end
|
||||
end
|
||||
|
||||
unless IssueQuery.included_modules.include?(RedmineChecklists::Patches::IssueQueryPatch)
|
||||
if (ActiveRecord::Base.connection.tables.include?('queries') rescue false) &&
|
||||
IssueQuery.included_modules.exclude?(RedmineChecklists::Patches::IssueQueryPatch)
|
||||
IssueQuery.send(:include, RedmineChecklists::Patches::IssueQueryPatch)
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
|
||||
# issue checklists management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2011-2017 RedmineUP
|
||||
# Copyright (C) 2011-2020 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_checklists is free software: you can redistribute it and/or modify
|
||||
|
@ -26,8 +26,9 @@ module RedmineChecklists
|
|||
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]
|
||||
alias_method :build_new_issue_from_params_without_checklist, :build_new_issue_from_params
|
||||
alias_method :build_new_issue_from_params, :build_new_issue_from_params_with_checklist
|
||||
before_action :save_before_state, :only => [:update]
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -44,6 +45,14 @@ module RedmineChecklists
|
|||
|
||||
def save_before_state
|
||||
@issue.old_checklists = @issue.checklists.to_json
|
||||
checklists_params = params[:issue].present? && params[:issue][:checklists_attributes].present? ? params[:issue][:checklists_attributes] : {}
|
||||
@issue.removed_checklist_ids =
|
||||
if checklists_params.present?
|
||||
checklists_params = checklists_params.respond_to?(:to_unsafe_hash) ? checklists_params.to_unsafe_hash : checklists_params
|
||||
checklists_params.map { |_k, v| v['id'].to_i if ['1', 'true'].include?(v['_destroy']) }.compact
|
||||
else
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
||||
def fill_checklist_attributes
|
||||
|
@ -60,14 +69,16 @@ module RedmineChecklists
|
|||
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 }
|
||||
params[:issue][:checklists_attributes][index.to_s] = {
|
||||
is_done: checklist_item.is_done,
|
||||
subject: checklist_item.subject,
|
||||
position: checklist_item.position,
|
||||
is_section: checklist_item.is_section
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
|
||||
# issue checklists management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2011-2017 RedmineUP
|
||||
# Copyright (C) 2011-2020 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_checklists is free software: you can redistribute it and/or modify
|
||||
|
@ -26,26 +26,18 @@ module RedmineChecklists
|
|||
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'
|
||||
alias_method :details_to_strings_without_checklists, :details_to_strings
|
||||
alias_method :details_to_strings, :details_to_strings_with_checklists
|
||||
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' }
|
||||
return details_to_strings_without_checklists(details_other, no_html, options) unless User.current.allowed_to?(:view_checklists, @issue.project)
|
||||
|
||||
details_checklist.map do |detail|
|
||||
result = []
|
||||
diff = Hash.new([])
|
||||
|
@ -56,15 +48,19 @@ module RedmineChecklists
|
|||
diff = JournalChecklistHistory.new(detail.old_value, detail.value).diff
|
||||
end
|
||||
|
||||
checklist_item_label = lambda do |item|
|
||||
item[:is_section] ? l(:label_checklist_section) : l(:label_checklist_item)
|
||||
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)}"
|
||||
result << "<b>#{ERB::Util.h l(:label_checklist_item)}</b> <input type='checkbox' class='checklist-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)}"
|
||||
result << "<b>#{ERB::Util.h l(:label_checklist_item)}</b> <input type='checkbox' class='checklist-checkbox' #{item.is_done ? 'checked' : '' } disabled> <i>#{ERB::Util.h item[:subject]}</i> #{ERB::Util.h l(:label_checklist_undone)}"
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -72,8 +68,8 @@ module RedmineChecklists
|
|||
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 /<input type='checkbox' class='checklist-checkbox'[^c^>]*checked[^>]*>/, '[x]'
|
||||
result = result.gsub /<input type='checkbox' class='checklist-checkbox'[^c^>]*>/, '[ ]'
|
||||
result = result.gsub /<[^>]*>/, ''
|
||||
result = CGI.unescapeHTML(result)
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
|
||||
# issue checklists management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2011-2017 RedmineUP
|
||||
# Copyright (C) 2011-2020 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_checklists is free software: you can redistribute it and/or modify
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
|
||||
# issue checklists management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2011-2017 RedmineUP
|
||||
# Copyright (C) 2011-2020 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_checklists is free software: you can redistribute it and/or modify
|
||||
|
@ -26,7 +26,8 @@ module RedmineChecklists
|
|||
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
|
||||
alias_method :copy_issues_without_checklist, :copy_issues
|
||||
alias_method :copy_issues, :copy_issues_with_checklist
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -34,7 +35,7 @@ module RedmineChecklists
|
|||
|
||||
def copy_issues_with_checklist(project)
|
||||
copy_issues_without_checklist(project)
|
||||
issues.each{ |issue| issue.copy_checklists(issue.copied_from)}
|
||||
issues.each{ |issue| issue.copy_checklists(issue.copied_from) if issue.reload.checklists.empty? }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
|
||||
# issue checklists management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2011-2017 RedmineUP
|
||||
# Copyright (C) 2011-2020 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_checklists is free software: you can redistribute it and/or modify
|
||||
|
@ -18,6 +18,8 @@
|
|||
# along with redmine_checklists. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Rails.configuration.to_prepare do
|
||||
require 'redmine_checklists/patches/compatibility/application_helper_patch'
|
||||
|
||||
require 'redmine_checklists/hooks/views_issues_hook'
|
||||
require 'redmine_checklists/hooks/views_layouts_hook'
|
||||
require 'redmine_checklists/hooks/controller_issues_hook'
|
||||
|
@ -33,5 +35,13 @@ Rails.configuration.to_prepare do
|
|||
end
|
||||
|
||||
module RedmineChecklists
|
||||
def self.settings() Setting[:plugin_redmine_checklists].blank? ? {} : Setting[:plugin_redmine_checklists] end
|
||||
def self.settings() Setting.plugin_redmine_checklists.blank? ? {} : Setting.plugin_redmine_checklists end
|
||||
|
||||
def self.block_issue_closing?
|
||||
settings['block_issue_closing'].to_i > 0
|
||||
end
|
||||
|
||||
def self.issue_done_ratio?
|
||||
settings['issue_done_ratio'].to_i > 0
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
#!/bin/bash
|
||||
RUBY=$1
|
||||
DB=$2
|
||||
REDMINE=$3
|
||||
|
||||
docker run -t -i -v `pwd`:/var/www/$RUBY/$DB/$REDMINE/plugins/redmine_checklists \
|
||||
--env RUBY=$1 \
|
||||
--env DB=$2 \
|
||||
--env REDMINE=$3 \
|
||||
--env PLUGIN=redmine_checklists \
|
||||
redmineup/redmine_checklists \
|
||||
/root/run_local.sh
|
|
@ -1,14 +1,25 @@
|
|||
# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
|
||||
---
|
||||
# === Checklist for Issue(1) ===
|
||||
one:
|
||||
id: 1
|
||||
is_done: false
|
||||
subject: First todo
|
||||
issue_id: 1
|
||||
|
||||
two:
|
||||
id: 2
|
||||
is_done: true
|
||||
subject: Second todo
|
||||
issue_id: 1
|
||||
|
||||
# === Checklist for Issue(2) ===
|
||||
section_one:
|
||||
id: 4
|
||||
is_done: false
|
||||
subject: New section
|
||||
is_section: true
|
||||
issue_id: 2
|
||||
|
||||
three:
|
||||
id: 3
|
||||
is_done: true
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
|
||||
# issue checklists management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2011-2017 RedmineUP
|
||||
# Copyright (C) 2011-2020 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_checklists is free software: you can redistribute it and/or modify
|
||||
|
@ -44,8 +44,7 @@ class ChecklistsControllerTest < ActionController::TestCase
|
|||
:journals,
|
||||
:journal_details,
|
||||
:queries
|
||||
RedmineChecklists::TestCase.create_fixtures(Redmine::Plugin.find(:redmine_checklists).directory + '/test/fixtures/',
|
||||
[:checklists])
|
||||
RedmineChecklists::TestCase.create_fixtures(Redmine::Plugin.find(:redmine_checklists).directory + '/test/fixtures/', [:checklists])
|
||||
|
||||
def setup
|
||||
RedmineChecklists::TestCase.prepare
|
||||
|
@ -61,7 +60,7 @@ class ChecklistsControllerTest < ActionController::TestCase
|
|||
# log_user('admin', 'admin')
|
||||
@request.session[:user_id] = 1
|
||||
|
||||
xhr :put, :done, :is_done => 'true', :id => '1'
|
||||
compatible_xhr_request :put, :done, :is_done => 'true', :id => '1'
|
||||
assert_response :success, 'Post done not working'
|
||||
assert_equal true, Checklist.find(1).is_done, 'Post done not working'
|
||||
end
|
||||
|
@ -70,7 +69,7 @@ class ChecklistsControllerTest < ActionController::TestCase
|
|||
# log_user('admin', 'admin')
|
||||
@request.session[:user_id] = 5
|
||||
|
||||
xhr :put, :done, :is_done => true, :id => "1"
|
||||
compatible_xhr_request :put, :done, :is_done => true, :id => "1"
|
||||
assert_response 403, "Post done accessible for all"
|
||||
end
|
||||
|
||||
|
@ -78,7 +77,7 @@ class ChecklistsControllerTest < ActionController::TestCase
|
|||
# log_user('admin', 'admin')
|
||||
@request.session[:user_id] = 1
|
||||
@controller = IssuesController.new
|
||||
get :show, :id => @issue_1.id
|
||||
compatible_request :get, :show, :id => @issue_1.id
|
||||
assert_select 'ul#checklist_items li#checklist_item_1', @checklist_1.subject, "Issue won't view for admin"
|
||||
end
|
||||
|
||||
|
@ -86,7 +85,7 @@ class ChecklistsControllerTest < ActionController::TestCase
|
|||
# log_user('anonymous', '')
|
||||
@request.session[:user_id] = 5
|
||||
@controller = IssuesController.new
|
||||
get :show, :id => @issue_1.id
|
||||
compatible_request :get, :show, :id => @issue_1.id
|
||||
assert_select 'ul#checklist_items', false, "Issue view for anonymous"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
|
||||
# issue checklists management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2011-2017 RedmineUP
|
||||
# Copyright (C) 2011-2020 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_checklists is free software: you can redistribute it and/or modify
|
||||
|
@ -49,71 +49,56 @@ class IssuesControllerTest < ActionController::TestCase
|
|||
:journal_details,
|
||||
:queries
|
||||
|
||||
|
||||
RedmineChecklists::TestCase.create_fixtures(Redmine::Plugin.find(:redmine_checklists).directory + '/test/fixtures/',
|
||||
[:checklists])
|
||||
|
||||
RedmineChecklists::TestCase.create_fixtures(Redmine::Plugin.find(:redmine_checklists).directory + '/test/fixtures/', [:checklists])
|
||||
|
||||
def setup
|
||||
@request.session[:user_id] = 1
|
||||
RedmineChecklists::TestCase.prepare
|
||||
end
|
||||
|
||||
def test_new_issue_without_project
|
||||
get :new
|
||||
compatible_request :get, :new
|
||||
assert_response :success
|
||||
end if Redmine::VERSION.to_s > '3.0'
|
||||
|
||||
def test_get_show_issue
|
||||
issue = Issue.find(1)
|
||||
assert_not_nil issue.checklists.first
|
||||
get :show, :id => 1
|
||||
compatible_request(:get, :show, :id => 1)
|
||||
assert_response :success
|
||||
assert_select "ul#checklist_items li#checklist_item_1", /First todo/
|
||||
assert_select "ul#checklist_items li#checklist_item_1 input[checked=?]", "checked", {:count => 0}
|
||||
assert_select "ul#checklist_items li#checklist_item_1 input[checked=?]", "checked", { :count => 0 }
|
||||
assert_select "ul#checklist_items li#checklist_item_2 input[checked=?]", "checked"
|
||||
end
|
||||
|
||||
def test_get_edit_issue
|
||||
get :edit, :id => 1
|
||||
compatible_request :get, :edit, :id => 1
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
def test_get_copy_issue
|
||||
get :new, :project_id => 1, :copy_from => 1
|
||||
compatible_request :get, :new, :project_id => 1, :copy_from => 1
|
||||
assert_response :success
|
||||
assert_select "span#checklist_form_items span.checklist-subject", {:count => 3}
|
||||
assert_select "span#checklist_form_items span.checklist-subject", { :count => 3 }
|
||||
assert_select "span#checklist_form_items span.checklist-edit input[value=?]", "First todo"
|
||||
end
|
||||
|
||||
def test_put_update_form
|
||||
parameters = {:tracker_id => 2,
|
||||
:checklists_attributes => {
|
||||
"0" => {"is_done"=>"0", "subject"=>"First"},
|
||||
"0" => {"is_done"=>"0", "subject"=>"FirstChecklist"},
|
||||
"1" => {"is_done"=>"0", "subject"=>"Second"}}}
|
||||
|
||||
@request.session[:user_id] = 1
|
||||
issue = Issue.find(1)
|
||||
if Redmine::VERSION.to_s > '2.3' && Redmine::VERSION.to_s < '3.0'
|
||||
xhr :put, :update_form,
|
||||
:issue => parameters,
|
||||
:project_id => issue.project
|
||||
compatible_xhr_request :put, :update_form, :issue => parameters, :project_id => issue.project
|
||||
else
|
||||
xhr :put, :new,
|
||||
:issue => parameters,
|
||||
:project_id => issue.project
|
||||
compatible_xhr_request :put, :new, :issue => parameters, :project_id => issue.project
|
||||
end
|
||||
assert_response :success
|
||||
assert_equal 'text/javascript', response.content_type
|
||||
|
||||
if Redmine::VERSION.to_s < '3.0'
|
||||
assert_template 'update_form'
|
||||
else
|
||||
assert_template 'new'
|
||||
end
|
||||
|
||||
issue = assigns(:issue)
|
||||
assert_kind_of Issue, issue
|
||||
assert_match 'First', issue.checklists.map(&:subject).join
|
||||
assert_match 'FirstChecklist', response.body
|
||||
end
|
||||
|
||||
def test_added_attachment_shows_in_log_once
|
||||
|
@ -125,11 +110,10 @@ class IssuesControllerTest < ActionController::TestCase
|
|||
'1' => { 'is_done' => '0', 'subject' => 'Second' } } }
|
||||
@request.session[:user_id] = 1
|
||||
issue = Issue.find(1)
|
||||
post :update,
|
||||
:issue => parameters,
|
||||
:attachments => { '1' => { 'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file' } },
|
||||
:project_id => issue.project,
|
||||
:id => issue.to_param
|
||||
compatible_request :post, :update, :issue => parameters,
|
||||
:attachments => { '1' => { 'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file' } },
|
||||
:project_id => issue.project,
|
||||
:id => issue.to_param
|
||||
assert_response :redirect
|
||||
assert_equal 1, Journal.last.details.where(:property => 'attachment').count
|
||||
end
|
||||
|
@ -144,7 +128,7 @@ class IssuesControllerTest < ActionController::TestCase
|
|||
:old_value => '[ ] TEST',
|
||||
:value => '[x] TEST')
|
||||
|
||||
post :show, :id => issue.id
|
||||
compatible_request :post, :show, :id => issue.id
|
||||
assert_response :success
|
||||
last_journal = issue.journals.last
|
||||
assert_equal last_journal.details.size, 1
|
||||
|
@ -156,7 +140,7 @@ class IssuesControllerTest < ActionController::TestCase
|
|||
@request.session[:user_id] = 1
|
||||
issue = Issue.find(1)
|
||||
journals_before = issue.journals.count
|
||||
post :update, :issue => {}, :id => issue.to_param, :project_id => issue.project
|
||||
compatible_request :post, :update, :issue => {}, :id => issue.to_param, :project_id => issue.project
|
||||
assert_response :redirect
|
||||
assert_equal journals_before, issue.reload.journals.count
|
||||
end
|
||||
|
@ -164,11 +148,11 @@ class IssuesControllerTest < ActionController::TestCase
|
|||
def test_create_issue_without_checklists
|
||||
@request.session[:user_id] = 1
|
||||
assert_difference 'Issue.count' do
|
||||
post :create, :project_id => 1, :issue => { :tracker_id => 3,
|
||||
:status_id => 2,
|
||||
:subject => 'NEW issue without checklists',
|
||||
:description => 'This is the description'
|
||||
}
|
||||
compatible_request :post, :create, :project_id => 1, :issue => { :tracker_id => 3,
|
||||
:status_id => 2,
|
||||
:subject => 'NEW issue without checklists',
|
||||
:description => 'This is the description'
|
||||
}
|
||||
end
|
||||
assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
|
||||
|
||||
|
@ -176,18 +160,36 @@ class IssuesControllerTest < ActionController::TestCase
|
|||
assert_not_nil issue
|
||||
end
|
||||
|
||||
def test_create_issue_with_checklists
|
||||
@request.session[:user_id] = 1
|
||||
assert_difference 'Issue.count' do
|
||||
compatible_request :post, :create, :project_id => 1, :issue => { :tracker_id => 3,
|
||||
:status_id => 2,
|
||||
:subject => 'NEW issue with checklists',
|
||||
:description => 'This is the description',
|
||||
:checklists_attributes => { '0' => { 'is_done' => '0', 'subject' => 'item 001', 'position' => '1' } }
|
||||
}
|
||||
end
|
||||
assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
|
||||
|
||||
issue = Issue.find_by_subject('NEW issue with checklists')
|
||||
assert_equal 1, issue.checklists.count
|
||||
assert_equal 'item 001', issue.checklists.last.subject
|
||||
assert_not_nil issue
|
||||
end
|
||||
|
||||
def test_create_issue_using_json
|
||||
old_value = Setting.rest_api_enabled
|
||||
Setting.rest_api_enabled = '1'
|
||||
@request.session[:user_id] = 1
|
||||
assert_difference 'Issue.count' do
|
||||
post :create, :format => :json, :project_id => 1, :issue => { :tracker_id => 3,
|
||||
:status_id => 2,
|
||||
:subject => 'NEW JSON issue',
|
||||
:description => 'This is the description',
|
||||
:checklists_attributes => [{:is_done => 0, :subject => 'JSON checklist'}]
|
||||
},
|
||||
:key => User.find(1).api_key
|
||||
compatible_request :post, :create, :format => :json, :project_id => 1, :issue => { :tracker_id => 3,
|
||||
:status_id => 2,
|
||||
:subject => 'NEW JSON issue',
|
||||
:description => 'This is the description',
|
||||
:checklists_attributes => [{ :is_done => 0, :subject => 'JSON checklist' }]
|
||||
},
|
||||
:key => User.find(1).api_key
|
||||
end
|
||||
assert_response :created
|
||||
|
||||
|
@ -197,4 +199,28 @@ class IssuesControllerTest < ActionController::TestCase
|
|||
ensure
|
||||
Setting.rest_api_enabled = old_value
|
||||
end
|
||||
|
||||
def test_history_displaying_for_checklist
|
||||
@request.session[:user_id] = 1
|
||||
Setting[:plugin_redmine_checklists] = { save_log: 1, issue_done_ratio: 0 }
|
||||
|
||||
issue = Issue.find(1)
|
||||
journal = issue.journals.create!(user_id: 1)
|
||||
journal.details.create!(:property => 'attr',
|
||||
:prop_key => 'checklist',
|
||||
:old_value => '[ ] TEST',
|
||||
:value => '[x] TEST')
|
||||
|
||||
# With permissions
|
||||
@request.session[:user_id] = 1
|
||||
compatible_request :get, :show, id: issue.id
|
||||
assert_response :success
|
||||
assert_include 'changed from [ ] TEST to [x] TEST', response.body
|
||||
|
||||
# Without permissions
|
||||
@request.session[:user_id] = 5
|
||||
compatible_request :get, :show, id: issue.id
|
||||
assert_response :success
|
||||
assert_not_include 'changed from [ ] TEST to [x] TEST', response.body
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
|
||||
# issue checklists management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2011-2017 RedmineUP
|
||||
# Copyright (C) 2011-2020 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_checklists is free software: you can redistribute it and/or modify
|
||||
|
@ -19,7 +19,7 @@
|
|||
# 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 File.dirname(__FILE__) + '/../../test_helper'
|
||||
require File.expand_path('../../../test_helper', __FILE__)
|
||||
|
||||
class Redmine::ApiTest::ChecklistsTest < Redmine::ApiTest::Base
|
||||
fixtures :projects,
|
||||
|
@ -46,27 +46,25 @@ class Redmine::ApiTest::ChecklistsTest < Redmine::ApiTest::Base
|
|||
:journal_details,
|
||||
:queries
|
||||
|
||||
RedmineChecklists::TestCase.create_fixtures(Redmine::Plugin.find(:redmine_checklists).directory + '/test/fixtures/',
|
||||
[:checklists])
|
||||
RedmineChecklists::TestCase.create_fixtures(Redmine::Plugin.find(:redmine_checklists).directory + '/test/fixtures/', [:checklists])
|
||||
|
||||
def setup
|
||||
Setting.rest_api_enabled = '1'
|
||||
end
|
||||
|
||||
def test_get_checklists_xml
|
||||
get '/issues/1/checklists.xml', {}, credentials('admin')
|
||||
compatible_api_request :get, '/issues/1/checklists.xml', {}, credentials('admin')
|
||||
|
||||
assert_select 'checklists[type=array]' do
|
||||
assert_select 'checklist' do
|
||||
assert_select 'id', :text => "1"
|
||||
assert_select 'subject', :text => "First todo"
|
||||
assert_select 'id', :text => '1'
|
||||
assert_select 'subject', :text => 'First todo'
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def test_get_checklists_1_xml
|
||||
get '/checklists/1.xml', {}, credentials('admin')
|
||||
compatible_api_request :get, '/checklists/1.xml', {}, credentials('admin')
|
||||
|
||||
assert_select 'checklist' do
|
||||
assert_select 'id', :text => '1'
|
||||
|
@ -75,11 +73,11 @@ class Redmine::ApiTest::ChecklistsTest < Redmine::ApiTest::Base
|
|||
end
|
||||
|
||||
def test_post_checklists_xml
|
||||
parameters = {:checklist => {:issue_id => 1,
|
||||
:subject => 'api_test_001',
|
||||
:is_done => true}}
|
||||
parameters = { :checklist => { :issue_id => 1,
|
||||
:subject => 'api_test_001',
|
||||
:is_done => true } }
|
||||
assert_difference('Checklist.count') do
|
||||
post '/issues/1/checklists.xml', parameters, credentials('admin')
|
||||
compatible_api_request :post, '/issues/1/checklists.xml', parameters, credentials('admin')
|
||||
end
|
||||
|
||||
checklist = Checklist.order('id DESC').first
|
||||
|
@ -91,25 +89,23 @@ class Redmine::ApiTest::ChecklistsTest < Redmine::ApiTest::Base
|
|||
end
|
||||
|
||||
def test_put_checklists_1_xml
|
||||
parameters = {:checklist => {:subject => 'Item_UPDATED'}}
|
||||
parameters = { :checklist => { subject: 'Item_UPDATED', is_done: '1' } }
|
||||
|
||||
assert_no_difference('Checklist.count') do
|
||||
put '/checklists/1.xml', parameters, credentials('admin')
|
||||
compatible_api_request :put, '/checklists/1.xml', parameters, credentials('admin')
|
||||
end
|
||||
|
||||
checklist = Checklist.find(1)
|
||||
assert_equal parameters[:checklist][:subject], checklist.subject
|
||||
|
||||
end
|
||||
|
||||
def test_delete_1_xml
|
||||
assert_difference 'Checklist.count', -1 do
|
||||
delete '/checklists/1.xml', {}, credentials('admin')
|
||||
compatible_api_request :delete, '/checklists/1.xml', {}, credentials('admin')
|
||||
end
|
||||
|
||||
assert_response :ok
|
||||
assert ['200', '204'].include?(response.code)
|
||||
assert_equal '', @response.body
|
||||
assert_nil Checklist.find_by_id(1)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
|
||||
# issue checklists management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2011-2017 RedmineUP
|
||||
# Copyright (C) 2011-2020 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_checklists is free software: you can redistribute it and/or modify
|
||||
|
@ -44,23 +44,19 @@ class CommonIssueTest < RedmineChecklists::IntegrationTest
|
|||
:journals,
|
||||
:journal_details,
|
||||
:queries
|
||||
RedmineChecklists::TestCase.create_fixtures(Redmine::Plugin.find(:redmine_checklists).directory + '/test/fixtures/',
|
||||
[:checklists])
|
||||
|
||||
RedmineChecklists::TestCase.create_fixtures(Redmine::Plugin.find(:redmine_checklists).directory + '/test/fixtures/', [:checklists])
|
||||
|
||||
def setup
|
||||
RedmineChecklists::TestCase.prepare
|
||||
Setting.default_language = 'en'
|
||||
@project_1 = Project.find(1)
|
||||
@issue_1 = Issue.find(1)
|
||||
@project_1 = Project.find(1)
|
||||
@issue_1 = Issue.find(1)
|
||||
@checklist_1 = Checklist.find(1)
|
||||
@request = ActionController::TestRequest.new
|
||||
end
|
||||
end
|
||||
|
||||
test "Global search with checklist" do
|
||||
# log_user('admin', 'admin')
|
||||
@request.session[:user_id] = 1
|
||||
get "/search?q=First"
|
||||
def test_global_search_with_checklist
|
||||
log_user('admin', 'admin')
|
||||
compatible_request :get, '/search?q=First'
|
||||
assert_response :success
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
|
||||
# issue checklists management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2011-2017 RedmineUP
|
||||
# Copyright (C) 2011-2020 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_checklists is free software: you can redistribute it and/or modify
|
||||
|
@ -21,6 +21,39 @@
|
|||
|
||||
require File.expand_path(File.dirname(__FILE__) + '/../../../test/test_helper')
|
||||
|
||||
module RedmineChecklists
|
||||
module TestHelper
|
||||
def compatible_request(type, action, parameters = {})
|
||||
return send(type, action, :params => parameters) if Rails.version >= '5.1'
|
||||
send(type, action, parameters)
|
||||
end
|
||||
|
||||
def compatible_xhr_request(type, action, parameters = {})
|
||||
return send(type, action, :params => parameters, :xhr => true) if Rails.version >= '5.1'
|
||||
xhr type, action, parameters
|
||||
end
|
||||
|
||||
def compatible_api_request(type, action, parameters = {}, headers = {})
|
||||
return send(type, action, :params => parameters, :headers => headers) if Redmine::VERSION.to_s >= '3.4'
|
||||
send(type, action, parameters, headers)
|
||||
end
|
||||
|
||||
def issues_in_list
|
||||
ids = css_select('tr.issue td.id a').map { |tag| tag.to_s.gsub(/<.*?>/, '') }.map(&:to_i)
|
||||
Issue.where(:id => ids).sort_by { |issue| ids.index(issue.id) }
|
||||
end
|
||||
|
||||
def with_checklists_settings(options, &block)
|
||||
Setting.plugin_redmine_checklists.stubs(:[]).returns(nil)
|
||||
options.each { |k, v| Setting.plugin_redmine_checklists.stubs(:[]).with(k).returns(v) }
|
||||
yield
|
||||
ensure
|
||||
options.each { |_k, _v| Setting.plugin_redmine_checklists.unstub(:[]) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
include RedmineChecklists::TestHelper
|
||||
|
||||
if ActiveRecord::VERSION::MAJOR >= 4
|
||||
class RedmineChecklists::IntegrationTest < Redmine::IntegrationTest; end
|
||||
|
@ -29,7 +62,6 @@ else
|
|||
end
|
||||
|
||||
class RedmineChecklists::TestCase
|
||||
|
||||
def self.create_fixtures(fixtures_directory, table_names, class_names = {})
|
||||
if ActiveRecord::VERSION::MAJOR >= 4
|
||||
ActiveRecord::FixtureSet.create_fixtures(fixtures_directory, table_names, class_names = {})
|
||||
|
@ -39,6 +71,11 @@ class RedmineChecklists::TestCase
|
|||
end
|
||||
|
||||
def self.prepare
|
||||
Role.find([1,2]).each do |r| # For anonymous
|
||||
r.permissions << :view_checklists
|
||||
r.save
|
||||
end
|
||||
|
||||
Role.find(1, 2, 3, 4).each do |r|
|
||||
r.permissions << :edit_checklists
|
||||
r.save
|
||||
|
@ -53,7 +90,5 @@ class RedmineChecklists::TestCase
|
|||
r.permissions << :manage_checklist_templates
|
||||
r.save
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
|
||||
# issue checklists management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2011-2017 RedmineUP
|
||||
# Copyright (C) 2011-2020 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_checklists is free software: you can redistribute it and/or modify
|
||||
|
@ -46,8 +46,7 @@ class ChecklistTest < ActiveSupport::TestCase
|
|||
:journal_details,
|
||||
:queries
|
||||
|
||||
RedmineChecklists::TestCase.create_fixtures(Redmine::Plugin.find(:redmine_checklists).directory + '/test/fixtures/',
|
||||
[:checklists])
|
||||
RedmineChecklists::TestCase.create_fixtures(Redmine::Plugin.find(:redmine_checklists).directory + '/test/fixtures/', [:checklists])
|
||||
def setup
|
||||
RedmineChecklists::TestCase.prepare
|
||||
Setting.default_language = 'en'
|
||||
|
@ -56,11 +55,8 @@ class ChecklistTest < ActiveSupport::TestCase
|
|||
:status_id => 1, :priority => IssuePriority.first,
|
||||
:subject => 'Invoice Issue 1')
|
||||
@checklist_1 = Checklist.create(:subject => 'TEST1', :position => 1, :issue => @issue_1)
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
test "should save checklist" do
|
||||
assert @checklist_1.save, "Checklist save error"
|
||||
end
|
||||
|
@ -90,4 +86,53 @@ class ChecklistTest < ActiveSupport::TestCase
|
|||
assert_equal "[x] #{@checklist_1.subject}", @checklist_1.info, "Helper info broken"
|
||||
end
|
||||
|
||||
def test_should_correct_recalculate_rate
|
||||
issues = [
|
||||
[Issue.create(project_id: 1, tracker_id: 1, author_id: 1, status_id: 1, priority: IssuePriority.first, subject: "TI #1", done_ratio: 0,
|
||||
checklists_attributes: {
|
||||
'0' => { subject: 'item 1', is_done: false },
|
||||
'1' => { subject: 'item 2', is_done: false },
|
||||
'2' => { subject: 'item 3', is_done: true },
|
||||
}),
|
||||
30],
|
||||
[Issue.create(project_id: 1, tracker_id: 1, author_id: 1, status_id: 1, priority: IssuePriority.first, subject: "TI #2", done_ratio: 0,
|
||||
checklists_attributes: {
|
||||
'0' => { subject: 'item 1', is_done: false },
|
||||
'1' => { subject: 'item 2', is_done: true },
|
||||
'2' => { subject: 'item 3', is_done: true },
|
||||
}),
|
||||
60],
|
||||
[Issue.create(project_id: 1, tracker_id: 1, author_id: 1, status_id: 1, priority: IssuePriority.first, subject: "TI #3", done_ratio: 0,
|
||||
checklists_attributes: {
|
||||
'0' => { subject: 'item 1', is_done: true },
|
||||
'1' => { subject: 'item 2', is_done: true },
|
||||
'2' => { subject: 'item 3', is_done: true },
|
||||
}),
|
||||
100],
|
||||
[Issue.create(project_id: 1, tracker_id: 1, author_id: 1, status_id: 1, priority: IssuePriority.first, subject: "TI #4", done_ratio: 0,
|
||||
checklists_attributes: {
|
||||
'0' => { subject: 'item 1', is_done: false },
|
||||
'1' => { subject: 'item 2', is_done: false },
|
||||
'2' => { subject: 'section 1', is_done: true, is_section: true },
|
||||
'3' => { subject: 'item 3', is_done: true },
|
||||
}),
|
||||
30],
|
||||
[Issue.create(project_id: 1, tracker_id: 1, author_id: 1, status_id: 1, priority: IssuePriority.first, subject: "TI #5", done_ratio: 0,
|
||||
checklists_attributes: {
|
||||
'0' => { subject: 'section 1', is_done: true, is_section: true }
|
||||
}),
|
||||
0]
|
||||
]
|
||||
|
||||
with_checklists_settings('issue_done_ratio' => '1') do
|
||||
issues.each do |issue, after_ratio|
|
||||
assert_equal 0, issue.done_ratio
|
||||
Checklist.recalc_issue_done_ratio(issue.id)
|
||||
issue.reload
|
||||
assert_equal after_ratio, issue.done_ratio
|
||||
end
|
||||
end
|
||||
ensure
|
||||
issues.each { |issue, ratio| issue.destroy }
|
||||
end
|
||||
end
|
||||
|
|
85
plugins/redmine_checklists/test/unit/issue_test.rb
Normal file
85
plugins/redmine_checklists/test/unit/issue_test.rb
Normal file
|
@ -0,0 +1,85 @@
|
|||
# encoding: utf-8
|
||||
#
|
||||
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
|
||||
# issue checklists management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2011-2020 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 File.expand_path('../../test_helper', __FILE__)
|
||||
include RedmineChecklists::TestHelper
|
||||
|
||||
class IssueTest < ActiveSupport::TestCase
|
||||
fixtures :projects,
|
||||
:users,
|
||||
:roles,
|
||||
:members,
|
||||
:member_roles,
|
||||
:issues,
|
||||
:issue_statuses,
|
||||
:versions,
|
||||
:trackers,
|
||||
:projects_trackers,
|
||||
:issue_categories,
|
||||
:enabled_modules,
|
||||
:enumerations,
|
||||
:attachments,
|
||||
:workflows,
|
||||
:custom_fields,
|
||||
:custom_values,
|
||||
:custom_fields_projects,
|
||||
:custom_fields_trackers,
|
||||
:time_entries,
|
||||
:journals,
|
||||
:journal_details,
|
||||
:queries
|
||||
|
||||
RedmineChecklists::TestCase.create_fixtures(Redmine::Plugin.find(:redmine_checklists).directory + '/test/fixtures/', [:checklists])
|
||||
def setup
|
||||
RedmineChecklists::TestCase.prepare
|
||||
Setting.default_language = 'en'
|
||||
@project = Project.find(1)
|
||||
@issue = Issue.create(:project => @project, :tracker_id => 1, :author_id => 1,
|
||||
:status_id => 1, :priority => IssuePriority.first,
|
||||
:subject => 'TestIssue')
|
||||
@checklist_1 = Checklist.create(:subject => 'TEST1', :position => 1, :issue => @issue)
|
||||
@checklist_2 = Checklist.create(:subject => 'TEST2', :position => 2, :issue => @issue, :is_done => true)
|
||||
@issue.reload
|
||||
end
|
||||
|
||||
def test_issue_shouldnt_close_when_it_has_unfinished_checklists
|
||||
with_checklists_settings('block_issue_closing' => '1') do
|
||||
@issue.status_id = 5
|
||||
assert !@issue.valid?
|
||||
end
|
||||
end
|
||||
|
||||
def test_validation_should_be_ignored_if_setting_disabled
|
||||
with_checklists_settings('block_issue_closing' => '0') do
|
||||
@issue.status_id = 5
|
||||
assert @issue.valid?
|
||||
end
|
||||
end
|
||||
|
||||
def test_issue_should_close_when_all_checklists_finished
|
||||
with_checklists_settings('block_issue_closing' => '1') do
|
||||
@checklist_1.update_attributes(:is_done => true)
|
||||
assert @issue.valid?
|
||||
end
|
||||
ensure
|
||||
@checklist_1.update_attributes(:is_done => false)
|
||||
end
|
||||
end
|
|
@ -3,7 +3,7 @@
|
|||
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
|
||||
# issue checklists management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2011-2017 RedmineUP
|
||||
# Copyright (C) 2011-2020 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_checklists is free software: you can redistribute it and/or modify
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue