Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 20 additions & 7 deletions app/controllers/checklists_controller.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
# issue checklists management plugin for Redmine
#
# Copyright (C) 2011-2018 RedmineUP
# Copyright (C) 2011-2020 RedmineUP
# http://www.redmineup.com/
#
# redmine_checklists is free software: you can redistribute it and/or modify
Expand Down Expand Up @@ -54,6 +54,7 @@ def create
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)
Expand All @@ -66,7 +67,8 @@ def update
@checklist_item.safe_attributes = params[:checklist]
respond_to do |format|
format.api {
if @checklist_item.save
if with_issue_journal { @checklist_item.save }
recalculate_issue_ratio(@checklist_item)
render_api_ok
else
render_validation_errors(@checklist_item)
Expand All @@ -77,12 +79,12 @@ def update

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|
Expand All @@ -106,4 +108,15 @@ def find_checklist_item
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
2 changes: 1 addition & 1 deletion app/helpers/checklists_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
# issue checklists management plugin for Redmine
#
# Copyright (C) 2011-2018 RedmineUP
# Copyright (C) 2011-2020 RedmineUP
# http://www.redmineup.com/
#
# redmine_checklists is free software: you can redistribute it and/or modify
Expand Down
10 changes: 5 additions & 5 deletions app/models/checklist.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
# issue checklists management plugin for Redmine
#
# Copyright (C) 2011-2018 RedmineUP
# Copyright (C) 2011-2020 RedmineUP
# http://www.redmineup.com/
#
# redmine_checklists is free software: you can redistribute it and/or modify
Expand Down Expand Up @@ -53,14 +53,14 @@ class Checklist < ActiveRecord::Base
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
Expand All @@ -70,7 +70,7 @@ def self.old_format?(detail)
(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)))
Expand Down
23 changes: 10 additions & 13 deletions app/models/journal_checklist_history.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# This file is a part of Redmine Checklists (redmine_checklists) plugin,
# issue checklists management plugin for Redmine
#
# Copyright (C) 2011-2018 RedmineUP
# Copyright (C) 2011-2020 RedmineUP
# http://www.redmineup.com/
#
# redmine_checklists is free software: you can redistribute it and/or modify
Expand All @@ -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)
Expand Down
15 changes: 9 additions & 6 deletions app/views/checklists/_checklist_item.html.erb
Original file line number Diff line number Diff line change
@@ -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>
13 changes: 13 additions & 0 deletions app/views/checklists/done.js.erb
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
9 changes: 6 additions & 3 deletions app/views/issues/_checklist.html.erb
Original file line number Diff line number Diff line change
@@ -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">
Expand All @@ -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 %>
37 changes: 21 additions & 16 deletions app/views/issues/_checklist_fields.html.erb
Original file line number Diff line number Diff line change
@@ -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>

Loading