##// END OF EJS Templates
Split user edit screen into tabs....
Jean-Philippe Lang -
r1389:63951812a1ed
parent child
Show More
@@ -0,0 +1,4
1 <% labelled_tabular_form_for :user, @user, :url => { :action => "edit" } do |f| %>
2 <%= render :partial => 'form', :locals => { :f => f } %>
3 <%= submit_tag l(:button_save) %>
4 <% end %>
@@ -1,113 +1,110
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
2 # Copyright (C) 2006-2007 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 UsersController < ApplicationController
18 class UsersController < ApplicationController
19 layout 'base'
19 layout 'base'
20 before_filter :require_admin
20 before_filter :require_admin
21
21
22 helper :sort
22 helper :sort
23 include SortHelper
23 include SortHelper
24 helper :custom_fields
24 helper :custom_fields
25 include CustomFieldsHelper
25 include CustomFieldsHelper
26
26
27 def index
27 def index
28 list
28 list
29 render :action => 'list' unless request.xhr?
29 render :action => 'list' unless request.xhr?
30 end
30 end
31
31
32 def list
32 def list
33 sort_init 'login', 'asc'
33 sort_init 'login', 'asc'
34 sort_update
34 sort_update
35
35
36 @status = params[:status] ? params[:status].to_i : 1
36 @status = params[:status] ? params[:status].to_i : 1
37 conditions = "status <> 0"
37 conditions = "status <> 0"
38 conditions = ["status=?", @status] unless @status == 0
38 conditions = ["status=?", @status] unless @status == 0
39
39
40 @user_count = User.count(:conditions => conditions)
40 @user_count = User.count(:conditions => conditions)
41 @user_pages = Paginator.new self, @user_count,
41 @user_pages = Paginator.new self, @user_count,
42 per_page_option,
42 per_page_option,
43 params['page']
43 params['page']
44 @users = User.find :all,:order => sort_clause,
44 @users = User.find :all,:order => sort_clause,
45 :conditions => conditions,
45 :conditions => conditions,
46 :limit => @user_pages.items_per_page,
46 :limit => @user_pages.items_per_page,
47 :offset => @user_pages.current.offset
47 :offset => @user_pages.current.offset
48
48
49 render :action => "list", :layout => false if request.xhr?
49 render :action => "list", :layout => false if request.xhr?
50 end
50 end
51
51
52 def add
52 def add
53 if request.get?
53 if request.get?
54 @user = User.new(:language => Setting.default_language)
54 @user = User.new(:language => Setting.default_language)
55 @custom_values = UserCustomField.find(:all, :order => "#{CustomField.table_name}.position").collect { |x| CustomValue.new(:custom_field => x, :customized => @user) }
55 @custom_values = UserCustomField.find(:all, :order => "#{CustomField.table_name}.position").collect { |x| CustomValue.new(:custom_field => x, :customized => @user) }
56 else
56 else
57 @user = User.new(params[:user])
57 @user = User.new(params[:user])
58 @user.admin = params[:user][:admin] || false
58 @user.admin = params[:user][:admin] || false
59 @user.login = params[:user][:login]
59 @user.login = params[:user][:login]
60 @user.password, @user.password_confirmation = params[:password], params[:password_confirmation] unless @user.auth_source_id
60 @user.password, @user.password_confirmation = params[:password], params[:password_confirmation] unless @user.auth_source_id
61 @custom_values = UserCustomField.find(:all, :order => "#{CustomField.table_name}.position").collect { |x| CustomValue.new(:custom_field => x, :customized => @user, :value => (params[:custom_fields] ? params["custom_fields"][x.id.to_s] : nil)) }
61 @custom_values = UserCustomField.find(:all, :order => "#{CustomField.table_name}.position").collect { |x| CustomValue.new(:custom_field => x, :customized => @user, :value => (params[:custom_fields] ? params["custom_fields"][x.id.to_s] : nil)) }
62 @user.custom_values = @custom_values
62 @user.custom_values = @custom_values
63 if @user.save
63 if @user.save
64 Mailer.deliver_account_information(@user, params[:password]) if params[:send_information]
64 Mailer.deliver_account_information(@user, params[:password]) if params[:send_information]
65 flash[:notice] = l(:notice_successful_create)
65 flash[:notice] = l(:notice_successful_create)
66 redirect_to :action => 'list'
66 redirect_to :action => 'list'
67 end
67 end
68 end
68 end
69 @auth_sources = AuthSource.find(:all)
69 @auth_sources = AuthSource.find(:all)
70 end
70 end
71
71
72 def edit
72 def edit
73 @user = User.find(params[:id])
73 @user = User.find(params[:id])
74 if request.get?
74 if request.get?
75 @custom_values = UserCustomField.find(:all, :order => "#{CustomField.table_name}.position").collect { |x| @user.custom_values.find_by_custom_field_id(x.id) || CustomValue.new(:custom_field => x) }
75 @custom_values = UserCustomField.find(:all, :order => "#{CustomField.table_name}.position").collect { |x| @user.custom_values.find_by_custom_field_id(x.id) || CustomValue.new(:custom_field => x) }
76 else
76 else
77 @user.admin = params[:user][:admin] if params[:user][:admin]
77 @user.admin = params[:user][:admin] if params[:user][:admin]
78 @user.login = params[:user][:login] if params[:user][:login]
78 @user.login = params[:user][:login] if params[:user][:login]
79 @user.password, @user.password_confirmation = params[:password], params[:password_confirmation] unless params[:password].nil? or params[:password].empty? or @user.auth_source_id
79 @user.password, @user.password_confirmation = params[:password], params[:password_confirmation] unless params[:password].nil? or params[:password].empty? or @user.auth_source_id
80 if params[:custom_fields]
80 if params[:custom_fields]
81 @custom_values = UserCustomField.find(:all, :order => "#{CustomField.table_name}.position").collect { |x| CustomValue.new(:custom_field => x, :customized => @user, :value => params["custom_fields"][x.id.to_s]) }
81 @custom_values = UserCustomField.find(:all, :order => "#{CustomField.table_name}.position").collect { |x| CustomValue.new(:custom_field => x, :customized => @user, :value => params["custom_fields"][x.id.to_s]) }
82 @user.custom_values = @custom_values
82 @user.custom_values = @custom_values
83 end
83 end
84 if @user.update_attributes(params[:user])
84 if @user.update_attributes(params[:user])
85 flash[:notice] = l(:notice_successful_update)
85 flash[:notice] = l(:notice_successful_update)
86 # Give a string to redirect_to otherwise it would use status param as the response code
86 # Give a string to redirect_to otherwise it would use status param as the response code
87 redirect_to(url_for(:action => 'list', :status => params[:status], :page => params[:page]))
87 redirect_to(url_for(:action => 'list', :status => params[:status], :page => params[:page]))
88 end
88 end
89 end
89 end
90 @auth_sources = AuthSource.find(:all)
90 @auth_sources = AuthSource.find(:all)
91 @roles = Role.find_all_givable
91 @roles = Role.find_all_givable
92 @projects = Project.find(:all, :order => 'name', :conditions => "status=#{Project::STATUS_ACTIVE}") - @user.projects
92 @projects = Project.find(:all, :order => 'name', :conditions => "status=#{Project::STATUS_ACTIVE}") - @user.projects
93 @membership ||= Member.new
93 @membership ||= Member.new
94 @memberships = @user.memberships
94 end
95 end
95
96
96 def edit_membership
97 def edit_membership
97 @user = User.find(params[:id])
98 @user = User.find(params[:id])
98 @membership = params[:membership_id] ? Member.find(params[:membership_id]) : Member.new(:user => @user)
99 @membership = params[:membership_id] ? Member.find(params[:membership_id]) : Member.new(:user => @user)
99 @membership.attributes = params[:membership]
100 @membership.attributes = params[:membership]
100 if request.post? and @membership.save
101 @membership.save if request.post?
101 flash[:notice] = l(:notice_successful_update)
102 redirect_to :action => 'edit', :id => @user, :tab => 'memberships'
102 end
103 redirect_to :action => 'edit', :id => @user and return
104 end
103 end
105
104
106 def destroy_membership
105 def destroy_membership
107 @user = User.find(params[:id])
106 @user = User.find(params[:id])
108 if request.post? and Member.find(params[:membership_id]).destroy
107 Member.find(params[:membership_id]).destroy if request.post?
109 flash[:notice] = l(:notice_successful_update)
108 redirect_to :action => 'edit', :id => @user, :tab => 'memberships'
110 end
111 redirect_to :action => 'edit', :id => @user and return
112 end
109 end
113 end
110 end
@@ -1,51 +1,57
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006 Jean-Philippe Lang
2 # Copyright (C) 2006 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 module UsersHelper
18 module UsersHelper
19 def status_options_for_select(selected)
19 def status_options_for_select(selected)
20 options_for_select([[l(:label_all), ''],
20 options_for_select([[l(:label_all), ''],
21 [l(:status_active), 1],
21 [l(:status_active), 1],
22 [l(:status_registered), 2],
22 [l(:status_registered), 2],
23 [l(:status_locked), 3]], selected)
23 [l(:status_locked), 3]], selected)
24 end
24 end
25
25
26 # Options for the new membership projects combo-box
26 # Options for the new membership projects combo-box
27 def projects_options_for_select(projects)
27 def projects_options_for_select(projects)
28 options = content_tag('option', "--- #{l(:actionview_instancetag_blank_option)} ---")
28 options = content_tag('option', "--- #{l(:actionview_instancetag_blank_option)} ---")
29 projects_by_root = projects.group_by(&:root)
29 projects_by_root = projects.group_by(&:root)
30 projects_by_root.keys.sort.each do |root|
30 projects_by_root.keys.sort.each do |root|
31 options << content_tag('option', h(root.name), :value => root.id, :disabled => (!projects.include?(root)))
31 options << content_tag('option', h(root.name), :value => root.id, :disabled => (!projects.include?(root)))
32 projects_by_root[root].sort.each do |project|
32 projects_by_root[root].sort.each do |project|
33 next if project == root
33 next if project == root
34 options << content_tag('option', '&#187; ' + h(project.name), :value => project.id)
34 options << content_tag('option', '&#187; ' + h(project.name), :value => project.id)
35 end
35 end
36 end
36 end
37 options
37 options
38 end
38 end
39
39
40 def change_status_link(user)
40 def change_status_link(user)
41 url = {:action => 'edit', :id => user, :page => params[:page], :status => params[:status]}
41 url = {:action => 'edit', :id => user, :page => params[:page], :status => params[:status]}
42
42
43 if user.locked?
43 if user.locked?
44 link_to l(:button_unlock), url.merge(:user => {:status => User::STATUS_ACTIVE}), :method => :post, :class => 'icon icon-unlock'
44 link_to l(:button_unlock), url.merge(:user => {:status => User::STATUS_ACTIVE}), :method => :post, :class => 'icon icon-unlock'
45 elsif user.registered?
45 elsif user.registered?
46 link_to l(:button_activate), url.merge(:user => {:status => User::STATUS_ACTIVE}), :method => :post, :class => 'icon icon-unlock'
46 link_to l(:button_activate), url.merge(:user => {:status => User::STATUS_ACTIVE}), :method => :post, :class => 'icon icon-unlock'
47 else
47 else
48 link_to l(:button_lock), url.merge(:user => {:status => User::STATUS_LOCKED}), :method => :post, :class => 'icon icon-lock'
48 link_to l(:button_lock), url.merge(:user => {:status => User::STATUS_LOCKED}), :method => :post, :class => 'icon icon-lock'
49 end
49 end
50 end
50 end
51
52 def user_settings_tabs
53 tabs = [{:name => 'general', :partial => 'users/general', :label => :label_general},
54 {:name => 'memberships', :partial => 'users/memberships', :label => :label_project_plural}
55 ]
56 end
51 end
57 end
@@ -1,32 +1,31
1 <%= error_messages_for 'user' %>
1 <%= error_messages_for 'user' %>
2
2
3 <!--[form:user]-->
3 <!--[form:user]-->
4 <div class="box">
4 <div class="box">
5 <h3><%=l(:label_information_plural)%></h3>
6 <p><%= f.text_field :login, :required => true, :size => 25 %></p>
5 <p><%= f.text_field :login, :required => true, :size => 25 %></p>
7 <p><%= f.text_field :firstname, :required => true %></p>
6 <p><%= f.text_field :firstname, :required => true %></p>
8 <p><%= f.text_field :lastname, :required => true %></p>
7 <p><%= f.text_field :lastname, :required => true %></p>
9 <p><%= f.text_field :mail, :required => true %></p>
8 <p><%= f.text_field :mail, :required => true %></p>
10 <p><%= f.select :language, lang_options_for_select %></p>
9 <p><%= f.select :language, lang_options_for_select %></p>
11
10
12 <% for @custom_value in @custom_values %>
11 <% for @custom_value in @custom_values %>
13 <p><%= custom_field_tag_with_label @custom_value %></p>
12 <p><%= custom_field_tag_with_label @custom_value %></p>
14 <% end if @custom_values%>
13 <% end if @custom_values%>
15
14
16 <p><%= f.check_box :admin %></p>
15 <p><%= f.check_box :admin %></p>
17 </div>
16 </div>
18
17
19 <div class="box">
18 <div class="box">
20 <h3><%=l(:label_authentication)%></h3>
19 <h3><%=l(:label_authentication)%></h3>
21 <% unless @auth_sources.empty? %>
20 <% unless @auth_sources.empty? %>
22 <p><%= f.select :auth_source_id, ([[l(:label_internal), ""]] + @auth_sources.collect { |a| [a.name, a.id] }), {}, :onchange => "if (this.value=='') {Element.show('password_fields');} else {Element.hide('password_fields');}" %></p>
21 <p><%= f.select :auth_source_id, ([[l(:label_internal), ""]] + @auth_sources.collect { |a| [a.name, a.id] }), {}, :onchange => "if (this.value=='') {Element.show('password_fields');} else {Element.hide('password_fields');}" %></p>
23 <% end %>
22 <% end %>
24 <div id="password_fields" style="<%= 'display:none;' if @user.auth_source %>">
23 <div id="password_fields" style="<%= 'display:none;' if @user.auth_source %>">
25 <p><label for="password"><%=l(:field_password)%><span class="required"> *</span></label>
24 <p><label for="password"><%=l(:field_password)%><span class="required"> *</span></label>
26 <%= password_field_tag 'password', nil, :size => 25 %><br />
25 <%= password_field_tag 'password', nil, :size => 25 %><br />
27 <em><%= l(:text_caracters_minimum, 4) %></em></p>
26 <em><%= l(:text_caracters_minimum, 4) %></em></p>
28 <p><label for="password_confirmation"><%=l(:field_password_confirmation)%><span class="required"> *</span></label>
27 <p><label for="password_confirmation"><%=l(:field_password_confirmation)%><span class="required"> *</span></label>
29 <%= password_field_tag 'password_confirmation', nil, :size => 25 %></p>
28 <%= password_field_tag 'password_confirmation', nil, :size => 25 %></p>
30 </div>
29 </div>
31 </div>
30 </div>
32 <!--[eoform:user]-->
31 <!--[eoform:user]-->
@@ -1,29 +1,40
1 <div class="box" style="margin-top: 16px;">
1 <% if @memberships.any? %>
2 <h3><%= l(:label_project_plural) %></h3>
2 <table class="list memberships">
3
3 <thead>
4 <% @user.memberships.each do |membership| %>
4 <th><%= l(:label_project) %></th>
5 <% form_tag({ :action => 'edit_membership', :id => @user, :membership_id => membership }, :class => "tabular") do %>
5 <th><%= l(:label_role) %></th>
6 <p style="margin:0;padding-top:0;">
6 <th style="width:15%"></th>
7 <label><%= membership.project.name %></label>
7 </thead>
8 <select name="membership[role_id]">
8 <tbody>
9 <%= options_from_collection_for_select @roles, "id", "name", membership.role_id %>
9 <% @memberships.each do |membership| %>
10 </select>
10 <% next if membership.new_record? %>
11 <%= submit_tag l(:button_change), :class => "button-small" %>
11 <tr class="<%= cycle 'odd', 'even' %>">
12 <%= link_to l(:button_delete), {:action => 'destroy_membership', :id => @user, :membership_id => membership }, :confirm => l(:text_are_you_sure), :method => :post, :class => 'icon icon-del' %>
12 <td><%=h membership.project %></td>
13 </p>
13 <td align="center">
14 <% form_tag({ :action => 'edit_membership', :id => @user, :membership_id => membership }) do %>
15 <%= select_tag 'membership[role_id]', options_from_collection_for_select(@roles, "id", "name", membership.role_id) %>
16 <%= submit_tag l(:button_change), :class => "small" %>
14 <% end %>
17 <% end %>
18 </td>
19 <td align="center">
20 <%= link_to l(:button_delete), {:action => 'destroy_membership', :id => @user, :membership_id => membership }, :method => :post, :class => 'icon icon-del' %>
21 </td>
22 </tr>
23 </tbody>
24 <% end; reset_cycle %>
25 </table>
26 <% else %>
27 <p class="nodata"><%= l(:label_no_data) %></p>
15 <% end %>
28 <% end %>
16
29
17 <% if @projects.any? %>
30 <% if @projects.any? %>
18 <hr />
19 <p>
31 <p>
20 <label><%=l(:label_project_new)%></label><br/>
32 <label><%=l(:label_project_new)%></label><br/>
21 <% form_tag({ :action => 'edit_membership', :id => @user }) do %>
33 <% form_tag({ :action => 'edit_membership', :id => @user }) do %>
22 <%= select_tag 'membership[project_id]', projects_options_for_select(@projects) %>
34 <%= select_tag 'membership[project_id]', projects_options_for_select(@projects) %>
23 <%= l(:label_role) %>:
35 <%= l(:label_role) %>:
24 <%= select_tag 'membership[role_id]', options_from_collection_for_select(@roles, "id", "name") %>
36 <%= select_tag 'membership[role_id]', options_from_collection_for_select(@roles, "id", "name") %>
25 <%= submit_tag l(:button_add) %>
37 <%= submit_tag l(:button_add) %>
26 <% end %>
38 <% end %>
27 </p>
39 </p>
28 <% end %>
40 <% end %>
29 </div> No newline at end of file
@@ -1,8 +1,23
1 <h2><%=l(:label_user)%></h2>
1 <h2><%=l(:label_user)%>: <%=h @user.login %></h2>
2
2
3 <% labelled_tabular_form_for :user, @user, :url => { :action => "edit" } do |f| %>
3 <% selected_tab = params[:tab] ? params[:tab].to_s : user_settings_tabs.first[:name] %>
4 <%= render :partial => 'form', :locals => { :f => f } %>
5 <%= submit_tag l(:button_save) %>
6 <% end %>
7
4
8 <%= render :partial => 'memberships' %> No newline at end of file
5 <div class="tabs">
6 <ul>
7 <% user_settings_tabs.each do |tab| -%>
8 <li><%= link_to l(tab[:label]), { :tab => tab[:name] },
9 :id => "tab-#{tab[:name]}",
10 :class => (tab[:name] != selected_tab ? nil : 'selected'),
11 :onclick => "showTab('#{tab[:name]}'); this.blur(); return false;" %></li>
12 <% end -%>
13 </ul>
14 </div>
15
16 <% user_settings_tabs.each do |tab| -%>
17 <%= content_tag('div', render(:partial => tab[:partial]),
18 :id => "tab-content-#{tab[:name]}",
19 :style => (tab[:name] != selected_tab ? 'display:none' : nil),
20 :class => 'tab-content') %>
21 <% end -%>
22
23 <% html_title(l(:label_user), @user.login, l(:label_administration)) -%>
General Comments 0
You need to be logged in to leave comments. Login now