To do #1285 » scrum_close_action_16.2.patch
app/controllers/sprints_controller.rb (working copy) | ||
---|---|---|
18 | 18 |
:stats, :sort] |
19 | 19 |
before_filter :find_project_by_project_id, |
20 | 20 |
:only => [:index, :new, :create, :change_task_status, :burndown_index, |
21 |
:stats_index] |
|
21 |
:stats_index, :update_pbi_status]
|
|
22 | 22 |
before_filter :find_pbis, :only => [:sort] |
23 | 23 |
before_filter :authorize |
24 | 24 | |
... | ... | |
111 | 111 |
@issue.due_date = Date.today |
112 | 112 |
end |
113 | 113 |
@issue.save! |
114 | ||
115 |
if @issue.is_pbi_task_closed? and |
|
116 |
!(Scrum::Setting.action_when_all_task_closed.nil?) and |
|
117 |
Scrum::Setting.action_when_all_task_closed.to_i == ActionCloseTask.actions[:ask_user] |
|
118 |
@askuser = true |
|
119 |
end |
|
120 | ||
114 | 121 |
respond_to do |format| |
115 | 122 |
format.js { render 'scrum/update_task' } |
116 | 123 |
end |
117 | 124 |
end |
118 | 125 | |
126 |
def update_pbi_status |
|
127 |
@pbi = Issue.find(params[:pbi].match(/^pbi_(\d+)$/)[1].to_i) |
|
128 |
@pbi.status = IssueStatus.find(params[:status].to_i) |
|
129 |
raise 'New status is not allowed' unless @pbi.new_statuses_allowed_to.include?(@pbi.status) |
|
130 |
@pbi.save! |
|
131 |
respond_to do |format| |
|
132 |
format.js { render 'scrum/update_pbi' } |
|
133 |
end |
|
134 |
end |
|
135 | ||
119 | 136 |
def edit_effort |
120 | 137 |
end |
121 | 138 |
app/models/action_close_task.rb (working copy) | ||
---|---|---|
1 |
class ActionCloseTask < ActiveRecord::Base |
|
2 |
|
|
3 |
enum action: [ :ask_user, :close_pbi ] |
|
4 |
|
|
5 |
end |
app/views/scrum/_ask_user_modal.html.erb (working copy) | ||
---|---|---|
1 |
<h3 class="title"><%= l(:label_ask_user_modal_title) %></h3> |
|
2 |
|
|
3 |
<div id="messages" /> |
|
4 |
|
|
5 |
<p>All the task are closed.</p> |
|
6 |
<p>Do you want to close the parent pbi ?</p> |
|
7 |
|
|
8 |
<p class="buttons"> |
|
9 |
<%= submit_tag l(:label_button_yes), :name => "Yes", :onclick => "UpdatePbiAndClose(this);", :type => "button" %> |
|
10 |
<%= submit_tag l(:label_button_no), :name => nil, :onclick => "hideModal(this);", :type => "button" %> |
|
11 |
</p> |
app/views/scrum/update_task.js.erb (working copy) | ||
---|---|---|
22 | 22 |
task.detach(); |
23 | 23 |
task.appendTo($("#<%= "pbi_#{@issue.parent_id}_status_#{@issue.status.id}" %>")); |
24 | 24 |
<%- end -%> |
25 |
<%- end -%> |
|
26 |
<%- if defined?(@askuser) -%> |
|
27 |
$("#ajax-modal").html("<%= escape_javascript(render :partial => "scrum/ask_user_modal") %>"); |
|
28 |
function UpdatePbiAndClose(modal){ |
|
29 |
hideModal(modal); |
|
30 |
if ($.isFunction($.fn.setupAjaxIndicator)) { |
|
31 |
setupAjaxIndicator(); |
|
32 |
} |
|
33 |
$.ajax({ |
|
34 |
url: "<%= project_sprints_update_pbi_status_path(@project) %>", |
|
35 |
type: "POST", |
|
36 |
data: {pbi: encodeURIComponent("pbi_<%= @issue.parent_id %>"), |
|
37 |
status: encodeURIComponent("<%= @issue.status.id %>")}, |
|
38 |
error: function() { |
|
39 |
alert("<%= l(:error_changing_pbi_status) %>"); |
|
40 |
location.reload(true); |
|
41 |
}, |
|
42 |
complete: function() { |
|
43 |
if ($.isFunction($.fn.hideOnLoad)) { |
|
44 |
hideOnLoad(); |
|
45 |
} |
|
46 |
} |
|
47 |
}); |
|
48 |
} |
|
49 |
showModal("ajax-modal", "300px"); |
|
25 | 50 |
<%- end -%> |
app/views/settings/_scrum_settings.html.erb (working copy) | ||
---|---|---|
67 | 67 |
<%- options = options_for_select(statuses, Scrum::Setting.status_id_set_enddate) -%> |
68 | 68 |
<%= select_tag 'settings[status_id_set_enddate]', options, :include_blank => true %> |
69 | 69 |
</p> |
70 |
<p> |
|
71 |
<label><%= l(:label_setting_action_when_all_task_closed) %>:</label> |
|
72 |
<%- actions = ActionCloseTask.actions.map{|s| [l('label_setting_actions_' + s[0]), s[1]]} -%> |
|
73 |
<%- options = options_for_select(actions, Scrum::Setting.action_when_all_task_closed) -%> |
|
74 |
<%= select_tag 'settings[action_when_all_task_closed]', options, :include_blank => true %> |
|
75 |
</p> |
|
70 | 76 |
</fieldset> |
71 | 77 | |
72 | 78 |
<fieldset> |
config/locales/en.yml (working copy) | ||
---|---|---|
19 | 19 |
error_no_sprints: "There are none Sprints defined yet, please ask this project administrator to create them in settings tab." |
20 | 20 |
error_updating_pbi: "Error updating the PBI (%{message})" |
21 | 21 |
error_updating_task: "Error updating the task (%{message})" |
22 |
error_changing_pbi_status: "Failed to update the pbi status. The page will be reloaded" |
|
22 | 23 |
field_end_date: "End date" |
23 | 24 |
field_pending_effort: "Pending effort" |
24 | 25 |
field_position: "Position" |
... | ... | |
99 | 100 |
label_setting_verification_activities: "Verification activities" |
100 | 101 |
label_setting_status_set_startdate: "Status that set the start date of the task" |
101 | 102 |
label_setting_status_set_enddate: "Status that set the end date of the task" |
103 |
label_setting_action_when_all_task_closed: "Action to do when all task are closed" |
|
104 |
label_setting_actions_ask_user: "Ask user" |
|
105 |
label_setting_actions_close_pbi: "Close parent pbi" |
|
102 | 106 |
label_scrum: "Scrum" |
103 | 107 |
label_sprint: "Sprint" |
104 | 108 |
label_sprint_board: "Sprint board" |
... | ... | |
152 | 156 |
label_velocity_custom: "Custom value:" |
153 | 157 |
label_velocity_only_scheduled_pbis: "Only scheduled ones" |
154 | 158 |
label_velocity_only_scheduled_pbis_hint: "This excludes from calculus any PBI created once the Sprint has started" |
159 |
label_ask_user_modal_title: "Ask user about action" |
|
160 |
label_button_yes: "Yes" |
|
161 |
label_button_no: "No" |
|
155 | 162 |
notice_pbi_created: "The product backlog item was successfully created" |
156 | 163 |
notice_sprint_has_issues: "The Sprint has issues" |
157 | 164 |
notice_task_created: "The task was successfully created" |
... | ... | |
169 | 176 |
permission_view_sprint_board: "View Sprint board" |
170 | 177 |
permission_view_sprint_burndown: "View Sprint burndown" |
171 | 178 |
permission_view_sprint_stats: "View Sprint stats" |
172 |
permission_view_sprint_stats_by_member: "View Sprint stats by member" |
|
179 |
permission_view_sprint_stats_by_member: "View Sprint stats by member"
|
|
173 | 180 |
date: |
174 | 181 |
formats: |
175 | 182 |
scrum_day: "%a" |
config/locales/fr.yml (working copy) | ||
---|---|---|
19 | 19 |
error_no_sprints: "Il n'y a aucun Sprint de défini pour le moment, merci de solliciter un administrateur du projet pour en créer dans l'onglet configuration." |
20 | 20 |
error_updating_pbi: "Erreur à la mise à jour du PBI (%{message})" |
21 | 21 |
error_updating_task: "Erreur à la mise à jour de la tâche (%{message})" |
22 |
error_changing_pbi_status: "Impossible de mettre à jour le status du PBI. La page va être rechargée." |
|
22 | 23 |
field_end_date: "Fin" |
23 | 24 |
field_pending_effort: "Reste à faire" |
24 | 25 |
field_position: "Partagé" |
... | ... | |
89 | 90 |
label_setting_verification_activities: "Vérification des activités" |
90 | 91 |
label_setting_status_set_startdate: "Statut qui ecrit la date de debut" |
91 | 92 |
label_setting_status_set_enddate: "Statut qui ecrit la date de fin" |
93 |
label_setting_action_when_all_task_closed: "Action a effectuer lorsque toutes les taches sont fermées" |
|
94 |
label_setting_actions_ask_user: "Demander a l'utilisateur" |
|
95 |
label_setting_actions_close_pbi: "Fermer le PBI" |
|
92 | 96 |
label_scrum: "Scrum" |
93 | 97 |
label_sprint: "Sprint" |
94 | 98 |
label_sprint_board: "Tableau de bord du Sprint" |
config/routes.rb (working copy) | ||
---|---|---|
26 | 26 |
post "sprints/change_task_status", |
27 | 27 |
:controller => :sprints, :action => :change_task_status, |
28 | 28 |
:as => :sprints_change_task_status |
29 |
post "sprints/update_pbi_status", |
|
30 |
:controller => :sprints, :action => :update_pbi_status, |
|
31 |
:as => :sprints_update_pbi_status |
|
29 | 32 | |
30 | 33 |
resources :product_backlog, :shallow => true do |
31 | 34 |
member do |
init.rb (working copy) | ||
---|---|---|
45 | 45 |
permission :view_sprint_board, |
46 | 46 |
{:sprints => [:index, :show]} |
47 | 47 |
permission :edit_sprint_board, |
48 |
{:sprints => [:change_task_status, :sort], |
|
48 |
{:sprints => [:change_task_status, :update_pbi_status, :sort],
|
|
49 | 49 |
:scrum => [:change_story_points, :change_pending_effort, :change_assigned_to, |
50 | 50 |
:new_pbi, :create_pbi, :edit_pbi, :update_pbi, |
51 | 51 |
:new_task, :create_task, :edit_task, :update_task]}, |
... | ... | |
110 | 110 |
:high_speed => 140, |
111 | 111 |
:render_plugin_tips => '1', |
112 | 112 |
:status_id_set_startdate => nil, |
113 |
:status_id_set_enddate => nil}, |
|
113 |
:status_id_set_enddate => nil, |
|
114 |
:action_when_all_task_closed => nil}, |
|
114 | 115 |
:partial => 'settings/scrum_settings' |
115 | 116 |
end |
lib/scrum/issue_patch.rb (working copy) | ||
---|---|---|
323 | 323 |
end |
324 | 324 |
end |
325 | 325 | |
326 |
def is_pbi_task_new? |
|
327 |
new_status = IssueStatus.task_statuses.first |
|
328 |
pbi = self.parent |
|
329 |
all_tasks_new = (self.status == new_status) |
|
330 |
pbi.children.each do |task| |
|
331 |
if task.is_task? |
|
332 |
task = self if task.id == self.id |
|
333 |
all_tasks_new = false if task.status != new_status |
|
334 |
end |
|
335 |
end |
|
336 |
return all_tasks_new |
|
337 |
end |
|
338 | ||
339 |
def is_pbi_task_closed? |
|
340 |
pbi = self.parent |
|
341 |
all_tasks_closed = (self.status.is_closed) |
|
342 |
pbi.children.each do |task| |
|
343 |
if task.is_task? |
|
344 |
task = self if task.id == self.id |
|
345 |
all_tasks_closed = false if !(task.status.is_closed) |
|
346 |
end |
|
347 |
end |
|
348 |
return all_tasks_closed |
|
349 |
end |
|
350 | ||
326 | 351 |
protected |
327 | 352 | |
328 | 353 |
def copy_attribute(source_issue, attribute) |
... | ... | |
378 | 403 |
if new_status && in_progress_status |
379 | 404 |
pbi = self.parent |
380 | 405 |
if pbi and pbi.is_pbi? |
381 |
all_tasks_new = (self.status == new_status) |
|
382 |
pbi.children.each do |task| |
|
383 |
if task.is_task? |
|
384 |
task = self if task.id == self.id |
|
385 |
all_tasks_new = false if task.status != new_status |
|
386 |
end |
|
387 |
end |
|
406 |
all_tasks_new = self.is_pbi_task_new? |
|
407 |
all_tasks_closed = self.is_pbi_task_closed? |
|
408 |
|
|
388 | 409 |
if pbi.status == new_status and !all_tasks_new |
389 | 410 |
pbi.status = in_progress_status |
390 | 411 |
pbi.save! |
391 | 412 |
elsif pbi.status != new_status and all_tasks_new |
392 | 413 |
pbi.status = new_status |
393 | 414 |
pbi.save! |
415 |
elsif pbi.status != new_status and all_tasks_closed |
|
416 |
if !(Scrum::Setting.action_when_all_task_closed.nil?) and |
|
417 |
Scrum::Setting.action_when_all_task_closed != "" |
|
418 |
case Scrum::Setting.action_when_all_task_closed.to_i |
|
419 |
when ActionCloseTask.actions[:close_pbi] |
|
420 |
pbi.status = self.status |
|
421 |
pbi.save! |
|
422 |
end |
|
423 |
end |
|
394 | 424 |
end |
395 | 425 |
end |
396 | 426 |
end |
lib/scrum/setting.rb (working copy) | ||
---|---|---|
65 | 65 |
end |
66 | 66 | |
67 | 67 |
%w(status_id_set_startdate |
68 |
status_id_set_enddate).each do |setting| |
|
68 |
status_id_set_enddate |
|
69 |
action_when_all_task_closed).each do |setting| |
|
69 | 70 |
src = <<-END_SRC |
70 | 71 |
def self.#{setting} |
71 | 72 |
::Setting.plugin_scrum[:#{setting}] |