##// END OF EJS Templates
Moving a custom field value in the order switches in the edit view (#21535)....
Jean-Philippe Lang -
r14603:227594481e2d
parent child
Show More
@@ -0,0 +1,38
1 # Redmine - project management software
2 # Copyright (C) 2006-2015 Jean-Philippe Lang
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
18 require File.expand_path('../base', __FILE__)
19
20 class Redmine::UiTest::CustomFieldsTest < Redmine::UiTest::Base
21 fixtures :projects, :users, :email_addresses, :roles, :members, :member_roles,
22 :trackers, :projects_trackers, :enabled_modules,
23 :custom_fields, :custom_values, :custom_fields_trackers
24
25 def test_reordering_should_redirect_to_index
26 assert_equal 1, UserCustomField.find(4).position
27 log_user 'admin', 'admin'
28 visit '/custom_fields'
29
30 # click 'User' tab
31 page.first('a#tab-UserCustomField').click
32 # click 'Move down' link on the first row
33 page.first('td.reorder a:nth-child(3)').click
34
35 assert_equal "/custom_fields?tab=UserCustomField", URI.parse(current_url).request_uri
36 assert_equal 2, UserCustomField.find(4).position
37 end
38 end
@@ -1,88 +1,88
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2015 Jean-Philippe Lang
2 # Copyright (C) 2006-2015 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 class CustomFieldsController < ApplicationController
18 class CustomFieldsController < ApplicationController
19 layout 'admin'
19 layout 'admin'
20
20
21 before_filter :require_admin
21 before_filter :require_admin
22 before_filter :build_new_custom_field, :only => [:new, :create]
22 before_filter :build_new_custom_field, :only => [:new, :create]
23 before_filter :find_custom_field, :only => [:edit, :update, :destroy]
23 before_filter :find_custom_field, :only => [:edit, :update, :destroy]
24 accept_api_auth :index
24 accept_api_auth :index
25
25
26 def index
26 def index
27 respond_to do |format|
27 respond_to do |format|
28 format.html {
28 format.html {
29 @custom_fields_by_type = CustomField.all.group_by {|f| f.class.name }
29 @custom_fields_by_type = CustomField.all.group_by {|f| f.class.name }
30 }
30 }
31 format.api {
31 format.api {
32 @custom_fields = CustomField.all
32 @custom_fields = CustomField.all
33 }
33 }
34 end
34 end
35 end
35 end
36
36
37 def new
37 def new
38 @custom_field.field_format = 'string' if @custom_field.field_format.blank?
38 @custom_field.field_format = 'string' if @custom_field.field_format.blank?
39 @custom_field.default_value = nil
39 @custom_field.default_value = nil
40 end
40 end
41
41
42 def create
42 def create
43 if @custom_field.save
43 if @custom_field.save
44 flash[:notice] = l(:notice_successful_create)
44 flash[:notice] = l(:notice_successful_create)
45 call_hook(:controller_custom_fields_new_after_save, :params => params, :custom_field => @custom_field)
45 call_hook(:controller_custom_fields_new_after_save, :params => params, :custom_field => @custom_field)
46 redirect_to edit_custom_field_path(@custom_field)
46 redirect_to edit_custom_field_path(@custom_field)
47 else
47 else
48 render :action => 'new'
48 render :action => 'new'
49 end
49 end
50 end
50 end
51
51
52 def edit
52 def edit
53 end
53 end
54
54
55 def update
55 def update
56 if @custom_field.update_attributes(params[:custom_field])
56 if @custom_field.update_attributes(params[:custom_field])
57 flash[:notice] = l(:notice_successful_update)
57 flash[:notice] = l(:notice_successful_update)
58 call_hook(:controller_custom_fields_edit_after_save, :params => params, :custom_field => @custom_field)
58 call_hook(:controller_custom_fields_edit_after_save, :params => params, :custom_field => @custom_field)
59 redirect_to edit_custom_field_path(@custom_field)
59 redirect_back_or_default edit_custom_field_path(@custom_field)
60 else
60 else
61 render :action => 'edit'
61 render :action => 'edit'
62 end
62 end
63 end
63 end
64
64
65 def destroy
65 def destroy
66 begin
66 begin
67 @custom_field.destroy
67 @custom_field.destroy
68 rescue
68 rescue
69 flash[:error] = l(:error_can_not_delete_custom_field)
69 flash[:error] = l(:error_can_not_delete_custom_field)
70 end
70 end
71 redirect_to custom_fields_path(:tab => @custom_field.class.name)
71 redirect_to custom_fields_path(:tab => @custom_field.class.name)
72 end
72 end
73
73
74 private
74 private
75
75
76 def build_new_custom_field
76 def build_new_custom_field
77 @custom_field = CustomField.new_subclass_instance(params[:type], params[:custom_field])
77 @custom_field = CustomField.new_subclass_instance(params[:type], params[:custom_field])
78 if @custom_field.nil?
78 if @custom_field.nil?
79 render :action => 'select_type'
79 render :action => 'select_type'
80 end
80 end
81 end
81 end
82
82
83 def find_custom_field
83 def find_custom_field
84 @custom_field = CustomField.find(params[:id])
84 @custom_field = CustomField.find(params[:id])
85 rescue ActiveRecord::RecordNotFound
85 rescue ActiveRecord::RecordNotFound
86 render_404
86 render_404
87 end
87 end
88 end
88 end
@@ -1,30 +1,31
1 <table class="list">
1 <table class="list">
2 <thead><tr>
2 <thead><tr>
3 <th><%=l(:field_name)%></th>
3 <th><%=l(:field_name)%></th>
4 <th><%=l(:field_field_format)%></th>
4 <th><%=l(:field_field_format)%></th>
5 <th><%=l(:field_is_required)%></th>
5 <th><%=l(:field_is_required)%></th>
6 <% if tab[:name] == 'IssueCustomField' %>
6 <% if tab[:name] == 'IssueCustomField' %>
7 <th><%=l(:field_is_for_all)%></th>
7 <th><%=l(:field_is_for_all)%></th>
8 <th><%=l(:label_used_by)%></th>
8 <th><%=l(:label_used_by)%></th>
9 <% end %>
9 <% end %>
10 <th><%=l(:button_sort)%></th>
10 <th><%=l(:button_sort)%></th>
11 <th></th>
11 <th></th>
12 </tr></thead>
12 </tr></thead>
13 <tbody>
13 <tbody>
14 <% (@custom_fields_by_type[tab[:name]] || []).sort.each do |custom_field| -%>
14 <% (@custom_fields_by_type[tab[:name]] || []).sort.each do |custom_field| -%>
15 <% back_url = custom_fields_path(:tab => tab[:name]) %>
15 <tr class="<%= cycle("odd", "even") %>">
16 <tr class="<%= cycle("odd", "even") %>">
16 <td class="name"><%= link_to custom_field.name, edit_custom_field_path(custom_field) %></td>
17 <td class="name"><%= link_to custom_field.name, edit_custom_field_path(custom_field) %></td>
17 <td><%= l(custom_field.format.label) %></td>
18 <td><%= l(custom_field.format.label) %></td>
18 <td><%= checked_image custom_field.is_required? %></td>
19 <td><%= checked_image custom_field.is_required? %></td>
19 <% if tab[:name] == 'IssueCustomField' %>
20 <% if tab[:name] == 'IssueCustomField' %>
20 <td><%= checked_image custom_field.is_for_all? %></td>
21 <td><%= checked_image custom_field.is_for_all? %></td>
21 <td><%= l(:label_x_projects, :count => custom_field.projects.count) if custom_field.is_a? IssueCustomField and !custom_field.is_for_all? %></td>
22 <td><%= l(:label_x_projects, :count => custom_field.projects.count) if custom_field.is_a? IssueCustomField and !custom_field.is_for_all? %></td>
22 <% end %>
23 <% end %>
23 <td class="reorder"><%= reorder_links('custom_field', {:action => 'update', :id => custom_field}, :put) %></td>
24 <td class="reorder"><%= reorder_links('custom_field', {:action => 'update', :id => custom_field, :back_url => back_url}, :put) %></td>
24 <td class="buttons">
25 <td class="buttons">
25 <%= delete_link custom_field_path(custom_field) %>
26 <%= delete_link custom_field_path(custom_field) %>
26 </td>
27 </td>
27 </tr>
28 </tr>
28 <% end; reset_cycle %>
29 <% end; reset_cycle %>
29 </tbody>
30 </tbody>
30 </table>
31 </table>
General Comments 0
You need to be logged in to leave comments. Login now