1 | NO CONTENT: new file 100644, binary diff hidden |
|
NO CONTENT: new file 100644, binary diff hidden |
@@ -174,6 +174,7 class IssuesController < ApplicationController | |||||
174 | @assignables << @issue.assigned_to if @issue.assigned_to && !@assignables.include?(@issue.assigned_to) |
|
174 | @assignables << @issue.assigned_to if @issue.assigned_to && !@assignables.include?(@issue.assigned_to) | |
175 | @can = {:edit => User.current.allowed_to?(:edit_issues, @project), |
|
175 | @can = {:edit => User.current.allowed_to?(:edit_issues, @project), | |
176 | :change_status => User.current.allowed_to?(:change_issue_status, @project), |
|
176 | :change_status => User.current.allowed_to?(:change_issue_status, @project), | |
|
177 | :add => User.current.allowed_to?(:add_issues, @project), | |||
177 | :move => User.current.allowed_to?(:move_issues, @project), |
|
178 | :move => User.current.allowed_to?(:move_issues, @project), | |
178 | :delete => User.current.allowed_to?(:delete_issues, @project)} |
|
179 | :delete => User.current.allowed_to?(:delete_issues, @project)} | |
179 | render :layout => false |
|
180 | render :layout => false |
@@ -192,43 +192,45 class ProjectsController < ApplicationController | |||||
192 | end |
|
192 | end | |
193 |
|
193 | |||
194 | # Add a new issue to @project |
|
194 | # Add a new issue to @project | |
|
195 | # The new issue will be created from an existing one if copy_from parameter is given | |||
195 | def add_issue |
|
196 | def add_issue | |
196 | @tracker = Tracker.find(params[:tracker_id]) |
|
197 | @issue = params[:copy_from] ? Issue.new.copy_from(params[:copy_from]) : Issue.new(params[:issue]) | |
197 | @priorities = Enumeration::get_values('IPRI') |
|
198 | @issue.project = @project | |
|
199 | @issue.author = User.current | |||
|
200 | @issue.tracker ||= Tracker.find(params[:tracker_id]) | |||
198 |
|
201 | |||
199 | default_status = IssueStatus.default |
|
202 | default_status = IssueStatus.default | |
200 | unless default_status |
|
203 | unless default_status | |
201 | flash.now[:error] = 'No default issue status defined. Please check your configuration.' |
|
204 | flash.now[:error] = 'No default issue status is defined. Please check your configuration (Go to "Administration -> Issue statuses").' | |
202 | render :nothing => true, :layout => true |
|
205 | render :nothing => true, :layout => true | |
203 | return |
|
206 | return | |
204 | end |
|
207 | end | |
205 | @issue = Issue.new(:project => @project, :tracker => @tracker) |
|
|||
206 | @issue.status = default_status |
|
208 | @issue.status = default_status | |
207 | @allowed_statuses = ([default_status] + default_status.find_new_statuses_allowed_to(logged_in_user.role_for_project(@project), @issue.tracker))if logged_in_user |
|
209 | @allowed_statuses = ([default_status] + default_status.find_new_statuses_allowed_to(logged_in_user.role_for_project(@project), @issue.tracker))if logged_in_user | |
|
210 | ||||
208 | if request.get? |
|
211 | if request.get? | |
209 | @issue.start_date = Date.today |
|
212 | @issue.start_date ||= Date.today | |
210 | @custom_values = @project.custom_fields_for_issues(@tracker).collect { |x| CustomValue.new(:custom_field => x, :customized => @issue) } |
|
213 | @custom_values = @issue.custom_values.empty? ? | |
|
214 | @project.custom_fields_for_issues(@issue.tracker).collect { |x| CustomValue.new(:custom_field => x, :customized => @issue) } : | |||
|
215 | @issue.custom_values | |||
211 | else |
|
216 | else | |
212 | @issue.attributes = params[:issue] |
|
|||
213 |
|
||||
214 | requested_status = IssueStatus.find_by_id(params[:issue][:status_id]) |
|
217 | requested_status = IssueStatus.find_by_id(params[:issue][:status_id]) | |
|
218 | # Check that the user is allowed to apply the requested status | |||
215 | @issue.status = (@allowed_statuses.include? requested_status) ? requested_status : default_status |
|
219 | @issue.status = (@allowed_statuses.include? requested_status) ? requested_status : default_status | |
216 |
|
220 | @custom_values = @project.custom_fields_for_issues(@issue.tracker).collect { |x| CustomValue.new(:custom_field => x, :customized => @issue, :value => params["custom_fields"][x.id.to_s]) } | ||
217 | @issue.author_id = self.logged_in_user.id if self.logged_in_user |
|
|||
218 | # Multiple file upload |
|
|||
219 | @attachments = [] |
|
|||
220 | params[:attachments].each { |a| |
|
|||
221 | @attachments << Attachment.new(:container => @issue, :file => a, :author => logged_in_user) unless a.size == 0 |
|
|||
222 | } if params[:attachments] and params[:attachments].is_a? Array |
|
|||
223 | @custom_values = @project.custom_fields_for_issues(@tracker).collect { |x| CustomValue.new(:custom_field => x, :customized => @issue, :value => params["custom_fields"][x.id.to_s]) } |
|
|||
224 | @issue.custom_values = @custom_values |
|
221 | @issue.custom_values = @custom_values | |
225 | if @issue.save |
|
222 | if @issue.save | |
226 | @attachments.each(&:save) |
|
223 | if params[:attachments] && params[:attachments].is_a?(Array) | |
|
224 | # Save attachments | |||
|
225 | params[:attachments].each {|a| Attachment.create(:container => @issue, :file => a, :author => User.current) unless a.size == 0} | |||
|
226 | end | |||
227 | flash[:notice] = l(:notice_successful_create) |
|
227 | flash[:notice] = l(:notice_successful_create) | |
228 | Mailer.deliver_issue_add(@issue) if Setting.notified_events.include?('issue_added') |
|
228 | Mailer.deliver_issue_add(@issue) if Setting.notified_events.include?('issue_added') | |
229 | redirect_to :action => 'list_issues', :id => @project |
|
229 | redirect_to :action => 'list_issues', :id => @project | |
|
230 | return | |||
230 | end |
|
231 | end | |
231 | end |
|
232 | end | |
|
233 | @priorities = Enumeration::get_values('IPRI') | |||
232 | end |
|
234 | end | |
233 |
|
235 | |||
234 | # Show filtered/sorted issues list of @project |
|
236 | # Show filtered/sorted issues list of @project |
@@ -54,6 +54,13 class Issue < ActiveRecord::Base | |||||
54 | end |
|
54 | end | |
55 | end |
|
55 | end | |
56 |
|
56 | |||
|
57 | def copy_from(arg) | |||
|
58 | issue = arg.is_a?(Issue) ? arg : Issue.find(arg) | |||
|
59 | self.attributes = issue.attributes.dup | |||
|
60 | self.custom_values = issue.custom_values.collect {|v| v.clone} | |||
|
61 | self | |||
|
62 | end | |||
|
63 | ||||
57 | def priority_id=(pid) |
|
64 | def priority_id=(pid) | |
58 | self.priority = nil |
|
65 | self.priority = nil | |
59 | write_attribute(:priority_id, pid) |
|
66 | write_attribute(:priority_id, pid) |
@@ -31,6 +31,8 | |||||
31 | :selected => @issue.assigned_to.nil?, :disabled => !(@can[:edit] || @can[:change_status]) %></li> |
|
31 | :selected => @issue.assigned_to.nil?, :disabled => !(@can[:edit] || @can[:change_status]) %></li> | |
32 | </ul> |
|
32 | </ul> | |
33 | </li> |
|
33 | </li> | |
|
34 | <li><%= context_menu_link l(:button_copy), {:controller => 'projects', :action => 'add_issue', :id => @project, :copy_from => @issue}, | |||
|
35 | :class => 'icon-copy', :disabled => !@can[:add] %></li> | |||
34 | <li><%= context_menu_link l(:button_move), {:controller => 'projects', :action => 'move_issues', :id => @project, "issue_ids[]" => @issue.id }, |
|
36 | <li><%= context_menu_link l(:button_move), {:controller => 'projects', :action => 'move_issues', :id => @project, "issue_ids[]" => @issue.id }, | |
35 | :class => 'icon-move', :disabled => !@can[:move] %> |
|
37 | :class => 'icon-move', :disabled => !@can[:move] %> | |
36 | <li><%= context_menu_link l(:button_delete), {:controller => 'issues', :action => 'destroy', :id => @issue}, |
|
38 | <li><%= context_menu_link l(:button_delete), {:controller => 'issues', :action => 'destroy', :id => @issue}, |
@@ -3,6 +3,7 | |||||
3 | <%= link_to_if_authorized l(:button_edit), {:controller => 'issues', :action => 'edit', :id => @issue}, :class => 'icon icon-edit', :accesskey => accesskey(:edit) %> |
|
3 | <%= link_to_if_authorized l(:button_edit), {:controller => 'issues', :action => 'edit', :id => @issue}, :class => 'icon icon-edit', :accesskey => accesskey(:edit) %> | |
4 | <%= link_to_if_authorized l(:button_log_time), {:controller => 'timelog', :action => 'edit', :issue_id => @issue}, :class => 'icon icon-time' %> |
|
4 | <%= link_to_if_authorized l(:button_log_time), {:controller => 'timelog', :action => 'edit', :issue_id => @issue}, :class => 'icon icon-time' %> | |
5 | <%= watcher_tag(@issue, User.current) %> |
|
5 | <%= watcher_tag(@issue, User.current) %> | |
|
6 | <%= link_to_if_authorized l(:button_copy), {:controller => 'projects', :action => 'add_issue', :id => @project, :copy_from => @issue }, :class => 'icon icon-copy' %> | |||
6 | <%= link_to_if_authorized l(:button_move), {:controller => 'projects', :action => 'move_issues', :id => @project, "issue_ids[]" => @issue.id }, :class => 'icon icon-move' %> |
|
7 | <%= link_to_if_authorized l(:button_move), {:controller => 'projects', :action => 'move_issues', :id => @project, "issue_ids[]" => @issue.id }, :class => 'icon icon-move' %> | |
7 | <%= link_to_if_authorized l(:button_delete), {:controller => 'issues', :action => 'destroy', :id => @issue}, :confirm => l(:text_are_you_sure), :method => :post, :class => 'icon icon-del' %> |
|
8 | <%= link_to_if_authorized l(:button_delete), {:controller => 'issues', :action => 'destroy', :id => @issue}, :confirm => l(:text_are_you_sure), :method => :post, :class => 'icon icon-del' %> | |
8 | </div> |
|
9 | </div> |
@@ -1,10 +1,10 | |||||
1 |
<h2><%=l(:label_issue_new)%>: <%= @ |
|
1 | <h2><%=l(:label_issue_new)%>: <%= @issue.tracker %></h2> | |
2 |
|
2 | |||
3 | <% labelled_tabular_form_for :issue, @issue, |
|
3 | <% labelled_tabular_form_for :issue, @issue, | |
4 | :url => {:action => 'add_issue'}, |
|
4 | :url => {:action => 'add_issue'}, | |
5 | :html => {:multipart => true, :id => 'issue-form'} do |f| %> |
|
5 | :html => {:multipart => true, :id => 'issue-form'} do |f| %> | |
6 |
<%= hidden_field |
|
6 | <%= f.hidden_field :tracker_id %> | |
7 |
<%= render :partial => 'issues/form', :locals => {:f => f} %> |
|
7 | <%= render :partial => 'issues/form', :locals => {:f => f} %> | |
8 | <%= submit_tag l(:button_create) %> |
|
8 | <%= submit_tag l(:button_create) %> | |
9 | <%= link_to_remote l(:label_preview), |
|
9 | <%= link_to_remote l(:label_preview), | |
10 | { :url => { :controller => 'issues', :action => 'preview', :id => @issue }, |
|
10 | { :url => { :controller => 'issues', :action => 'preview', :id => @issue }, |
@@ -476,6 +476,7 button_unarchive: Unarchive | |||||
476 | button_reset: Reset |
|
476 | button_reset: Reset | |
477 | button_rename: Rename |
|
477 | button_rename: Rename | |
478 | button_change_password: Change password |
|
478 | button_change_password: Change password | |
|
479 | button_copy: Copy | |||
479 |
|
480 | |||
480 | status_active: active |
|
481 | status_active: active | |
481 | status_registered: registered |
|
482 | status_registered: registered |
@@ -476,6 +476,7 button_unarchive: Désarchiver | |||||
476 | button_reset: Réinitialiser |
|
476 | button_reset: Réinitialiser | |
477 | button_rename: Renommer |
|
477 | button_rename: Renommer | |
478 | button_change_password: Changer de mot de passe |
|
478 | button_change_password: Changer de mot de passe | |
|
479 | button_copy: Copier | |||
479 |
|
480 | |||
480 | status_active: actif |
|
481 | status_active: actif | |
481 | status_registered: enregistré |
|
482 | status_registered: enregistré |
@@ -421,6 +421,7 vertical-align: middle; | |||||
421 |
|
421 | |||
422 | .icon-add { background-image: url(../images/add.png); } |
|
422 | .icon-add { background-image: url(../images/add.png); } | |
423 | .icon-edit { background-image: url(../images/edit.png); } |
|
423 | .icon-edit { background-image: url(../images/edit.png); } | |
|
424 | .icon-copy { background-image: url(../images/copy.png); } | |||
424 | .icon-del { background-image: url(../images/delete.png); } |
|
425 | .icon-del { background-image: url(../images/delete.png); } | |
425 | .icon-move { background-image: url(../images/move.png); } |
|
426 | .icon-move { background-image: url(../images/move.png); } | |
426 | .icon-save { background-image: url(../images/save.png); } |
|
427 | .icon-save { background-image: url(../images/save.png); } |
@@ -22,7 +22,7 require 'projects_controller' | |||||
22 | class ProjectsController; def rescue_action(e) raise e end; end |
|
22 | class ProjectsController; def rescue_action(e) raise e end; end | |
23 |
|
23 | |||
24 | class ProjectsControllerTest < Test::Unit::TestCase |
|
24 | class ProjectsControllerTest < Test::Unit::TestCase | |
25 | fixtures :projects, :users, :roles, :enabled_modules, :enumerations |
|
25 | fixtures :projects, :users, :roles, :members, :issues, :enabled_modules, :enumerations | |
26 |
|
26 | |||
27 | def setup |
|
27 | def setup | |
28 | @controller = ProjectsController.new |
|
28 | @controller = ProjectsController.new | |
@@ -143,4 +143,23 class ProjectsControllerTest < Test::Unit::TestCase | |||||
143 | assert_redirected_to 'admin/projects' |
|
143 | assert_redirected_to 'admin/projects' | |
144 | assert Project.find(1).active? |
|
144 | assert Project.find(1).active? | |
145 | end |
|
145 | end | |
|
146 | ||||
|
147 | def test_add_issue | |||
|
148 | @request.session[:user_id] = 2 | |||
|
149 | get :add_issue, :id => 1, :tracker_id => 1 | |||
|
150 | assert_response :success | |||
|
151 | assert_template 'add_issue' | |||
|
152 | post :add_issue, :id => 1, :issue => {:tracker_id => 1, :subject => 'This is the test_add_issue issue', :description => 'This is the description', :priority_id => 5} | |||
|
153 | assert_redirected_to 'projects/list_issues' | |||
|
154 | assert Issue.find_by_subject('This is the test_add_issue issue') | |||
|
155 | end | |||
|
156 | ||||
|
157 | def test_copy_issue | |||
|
158 | @request.session[:user_id] = 2 | |||
|
159 | get :add_issue, :id => 1, :copy_from => 1 | |||
|
160 | assert_template 'add_issue' | |||
|
161 | assert_not_nil assigns(:issue) | |||
|
162 | orig = Issue.find(1) | |||
|
163 | assert_equal orig.subject, assigns(:issue).subject | |||
|
164 | end | |||
146 | end |
|
165 | end |
@@ -18,13 +18,23 | |||||
18 | require File.dirname(__FILE__) + '/../test_helper' |
|
18 | require File.dirname(__FILE__) + '/../test_helper' | |
19 |
|
19 | |||
20 | class IssueTest < Test::Unit::TestCase |
|
20 | class IssueTest < Test::Unit::TestCase | |
21 | fixtures :projects, :users, :members, :trackers, :issue_statuses, :issue_categories, :enumerations, :issues |
|
21 | fixtures :projects, :users, :members, :trackers, :issue_statuses, :issue_categories, :enumerations, :issues, :custom_fields, :custom_values | |
22 |
|
22 | |||
23 | def test_category_based_assignment |
|
23 | def test_category_based_assignment | |
24 | issue = Issue.create(:project_id => 1, :tracker_id => 1, :author_id => 3, :status_id => 1, :priority => Enumeration.get_values('IPRI').first, :subject => 'Assignment test', :description => 'Assignment test', :category_id => 1) |
|
24 | issue = Issue.create(:project_id => 1, :tracker_id => 1, :author_id => 3, :status_id => 1, :priority => Enumeration.get_values('IPRI').first, :subject => 'Assignment test', :description => 'Assignment test', :category_id => 1) | |
25 | assert_equal IssueCategory.find(1).assigned_to, issue.assigned_to |
|
25 | assert_equal IssueCategory.find(1).assigned_to, issue.assigned_to | |
26 | end |
|
26 | end | |
27 |
|
27 | |||
|
28 | def test_copy | |||
|
29 | issue = Issue.new.copy_from(1) | |||
|
30 | assert issue.save | |||
|
31 | issue.reload | |||
|
32 | orig = Issue.find(1) | |||
|
33 | assert_equal orig.subject, issue.subject | |||
|
34 | assert_equal orig.tracker, issue.tracker | |||
|
35 | assert_equal orig.custom_values.first.value, issue.custom_values.first.value | |||
|
36 | end | |||
|
37 | ||||
28 | def test_close_duplicates |
|
38 | def test_close_duplicates | |
29 | # Create 3 issues |
|
39 | # Create 3 issues | |
30 | issue1 = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :priority => Enumeration.get_values('IPRI').first, :subject => 'Duplicates test', :description => 'Duplicates test') |
|
40 | issue1 = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :priority => Enumeration.get_values('IPRI').first, :subject => 'Duplicates test', :description => 'Duplicates test') |
General Comments 0
You need to be logged in to leave comments.
Login now