##// END OF EJS Templates
Fixed: changing user/roles of project member not possible without javascript (#4852)...
Jean-Philippe Lang -
r3369:f7bd0801f6dc
parent child
Show More
@@ -1,82 +1,82
1 <%= error_messages_for 'member' %>
1 <%= error_messages_for 'member' %>
2 <% roles = Role.find_all_givable
2 <% roles = Role.find_all_givable
3 members = @project.member_principals.find(:all, :include => [:roles, :principal]).sort %>
3 members = @project.member_principals.find(:all, :include => [:roles, :principal]).sort %>
4
4
5 <div class="splitcontentleft">
5 <div class="splitcontentleft">
6 <% if members.any? %>
6 <% if members.any? %>
7 <table class="list members">
7 <table class="list members">
8 <thead>
8 <thead>
9 <th><%= l(:label_user) %> / <%= l(:label_group) %></th>
9 <th><%= l(:label_user) %> / <%= l(:label_group) %></th>
10 <th><%= l(:label_role_plural) %></th>
10 <th><%= l(:label_role_plural) %></th>
11 <th style="width:15%"></th>
11 <th style="width:15%"></th>
12 <%= call_hook(:view_projects_settings_members_table_header, :project => @project) %>
12 <%= call_hook(:view_projects_settings_members_table_header, :project => @project) %>
13 </thead>
13 </thead>
14 <tbody>
14 <tbody>
15 <% members.each do |member| %>
15 <% members.each do |member| %>
16 <% next if member.new_record? %>
16 <% next if member.new_record? %>
17 <tr id="member-<%= member.id %>" class="<%= cycle 'odd', 'even' %> member">
17 <tr id="member-<%= member.id %>" class="<%= cycle 'odd', 'even' %> member">
18 <td class="<%= member.principal.class.name.downcase %>"><%= link_to_user member.principal %></td>
18 <td class="<%= member.principal.class.name.downcase %>"><%= link_to_user member.principal %></td>
19 <td class="roles">
19 <td class="roles">
20 <span id="member-<%= member.id %>-roles"><%=h member.roles.sort.collect(&:to_s).join(', ') %></span>
20 <span id="member-<%= member.id %>-roles"><%=h member.roles.sort.collect(&:to_s).join(', ') %></span>
21 <% if authorize_for('members', 'edit') %>
21 <% if authorize_for('members', 'edit') %>
22 <% remote_form_for(:member, member, :url => {:controller => 'members', :action => 'edit', :id => member},
22 <% remote_form_for(:member, member, :url => {:controller => 'members', :action => 'edit', :id => member},
23 :method => :post,
23 :method => :post,
24 :html => { :id => "member-#{member.id}-roles-form", :style => 'display:none;' }) do |f| %>
24 :html => { :id => "member-#{member.id}-roles-form", :class => 'hol' }) do |f| %>
25 <p><% roles.each do |role| %>
25 <p><% roles.each do |role| %>
26 <label><%= check_box_tag 'member[role_ids][]', role.id, member.roles.include?(role),
26 <label><%= check_box_tag 'member[role_ids][]', role.id, member.roles.include?(role),
27 :disabled => member.member_roles.detect {|mr| mr.role_id == role.id && !mr.inherited_from.nil?} %> <%=h role %></label><br />
27 :disabled => member.member_roles.detect {|mr| mr.role_id == role.id && !mr.inherited_from.nil?} %> <%=h role %></label><br />
28 <% end %></p>
28 <% end %></p>
29 <%= hidden_field_tag 'member[role_ids][]', '' %>
29 <%= hidden_field_tag 'member[role_ids][]', '' %>
30 <p><%= submit_tag l(:button_change), :class => "small" %>
30 <p><%= submit_tag l(:button_change), :class => "small" %>
31 <%= link_to_function l(:button_cancel), "$('member-#{member.id}-roles').show(); $('member-#{member.id}-roles-form').hide(); return false;" %></p>
31 <%= link_to_function l(:button_cancel), "$('member-#{member.id}-roles').show(); $('member-#{member.id}-roles-form').hide(); return false;" %></p>
32 <% end %>
32 <% end %>
33 <% end %>
33 <% end %>
34 </td>
34 </td>
35 <td class="buttons">
35 <td class="buttons">
36 <%= link_to_function l(:button_edit), "$('member-#{member.id}-roles').hide(); $('member-#{member.id}-roles-form').show(); return false;", :class => 'icon icon-edit' %>
36 <%= link_to_function l(:button_edit), "$('member-#{member.id}-roles').hide(); $('member-#{member.id}-roles-form').show(); return false;", :class => 'icon icon-edit' %>
37 <%= link_to_remote(l(:button_delete), { :url => {:controller => 'members', :action => 'destroy', :id => member},
37 <%= link_to_remote(l(:button_delete), { :url => {:controller => 'members', :action => 'destroy', :id => member},
38 :method => :post,
38 :method => :post,
39 :confirm => (!User.current.admin? && member.include?(User.current) ? l(:text_own_membership_delete_confirmation) : nil)
39 :confirm => (!User.current.admin? && member.include?(User.current) ? l(:text_own_membership_delete_confirmation) : nil)
40 }, :title => l(:button_delete),
40 }, :title => l(:button_delete),
41 :class => 'icon icon-del') if member.deletable? %>
41 :class => 'icon icon-del') if member.deletable? %>
42 </td>
42 </td>
43 <%= call_hook(:view_projects_settings_members_table_row, { :project => @project, :member => member}) %>
43 <%= call_hook(:view_projects_settings_members_table_row, { :project => @project, :member => member}) %>
44 </tr>
44 </tr>
45 </tbody>
45 </tbody>
46 <% end; reset_cycle %>
46 <% end; reset_cycle %>
47 </table>
47 </table>
48 <% else %>
48 <% else %>
49 <p class="nodata"><%= l(:label_no_data) %></p>
49 <p class="nodata"><%= l(:label_no_data) %></p>
50 <% end %>
50 <% end %>
51 </div>
51 </div>
52
52
53
53
54 <% principals = Principal.active.find(:all, :limit => 100, :order => 'type, login, lastname ASC') - @project.principals %>
54 <% principals = Principal.active.find(:all, :limit => 100, :order => 'type, login, lastname ASC') - @project.principals %>
55
55
56 <div class="splitcontentright">
56 <div class="splitcontentright">
57 <% if roles.any? && principals.any? %>
57 <% if roles.any? && principals.any? %>
58 <% remote_form_for(:member, @member, :url => {:controller => 'members', :action => 'new', :id => @project}, :method => :post) do |f| %>
58 <% remote_form_for(:member, @member, :url => {:controller => 'members', :action => 'new', :id => @project}, :method => :post) do |f| %>
59 <fieldset><legend><%=l(:label_member_new)%></legend>
59 <fieldset><legend><%=l(:label_member_new)%></legend>
60
60
61 <p><%= text_field_tag 'principal_search', nil, :size => "40" %></p>
61 <p><%= text_field_tag 'principal_search', nil, :size => "40" %></p>
62 <%= observe_field(:principal_search,
62 <%= observe_field(:principal_search,
63 :frequency => 0.5,
63 :frequency => 0.5,
64 :update => :principals,
64 :update => :principals,
65 :url => { :controller => 'members', :action => 'autocomplete_for_member', :id => @project },
65 :url => { :controller => 'members', :action => 'autocomplete_for_member', :id => @project },
66 :with => 'q')
66 :with => 'q')
67 %>
67 %>
68
68
69 <div id="principals">
69 <div id="principals">
70 <%= principals_check_box_tags 'member[user_ids][]', principals %>
70 <%= principals_check_box_tags 'member[user_ids][]', principals %>
71 </div>
71 </div>
72
72
73 <p><%= l(:label_role_plural) %>:
73 <p><%= l(:label_role_plural) %>:
74 <% roles.each do |role| %>
74 <% roles.each do |role| %>
75 <label><%= check_box_tag 'member[role_ids][]', role.id %> <%=h role %></label>
75 <label><%= check_box_tag 'member[role_ids][]', role.id %> <%=h role %></label>
76 <% end %></p>
76 <% end %></p>
77
77
78 <p><%= submit_tag l(:button_add) %></p>
78 <p><%= submit_tag l(:button_add) %></p>
79 </fieldset>
79 </fieldset>
80 <% end %>
80 <% end %>
81 <% end %>
81 <% end %>
82 </div>
82 </div>
@@ -1,209 +1,215
1 /* redMine - project management software
1 /* redMine - project management software
2 Copyright (C) 2006-2008 Jean-Philippe Lang */
2 Copyright (C) 2006-2008 Jean-Philippe Lang */
3
3
4 function checkAll (id, checked) {
4 function checkAll (id, checked) {
5 var els = Element.descendants(id);
5 var els = Element.descendants(id);
6 for (var i = 0; i < els.length; i++) {
6 for (var i = 0; i < els.length; i++) {
7 if (els[i].disabled==false) {
7 if (els[i].disabled==false) {
8 els[i].checked = checked;
8 els[i].checked = checked;
9 }
9 }
10 }
10 }
11 }
11 }
12
12
13 function toggleCheckboxesBySelector(selector) {
13 function toggleCheckboxesBySelector(selector) {
14 boxes = $$(selector);
14 boxes = $$(selector);
15 var all_checked = true;
15 var all_checked = true;
16 for (i = 0; i < boxes.length; i++) { if (boxes[i].checked == false) { all_checked = false; } }
16 for (i = 0; i < boxes.length; i++) { if (boxes[i].checked == false) { all_checked = false; } }
17 for (i = 0; i < boxes.length; i++) { boxes[i].checked = !all_checked; }
17 for (i = 0; i < boxes.length; i++) { boxes[i].checked = !all_checked; }
18 }
18 }
19
19
20 function showAndScrollTo(id, focus) {
20 function showAndScrollTo(id, focus) {
21 Element.show(id);
21 Element.show(id);
22 if (focus!=null) { Form.Element.focus(focus); }
22 if (focus!=null) { Form.Element.focus(focus); }
23 Element.scrollTo(id);
23 Element.scrollTo(id);
24 }
24 }
25
25
26 function toggleRowGroup(el) {
26 function toggleRowGroup(el) {
27 var tr = Element.up(el, 'tr');
27 var tr = Element.up(el, 'tr');
28 var n = Element.next(tr);
28 var n = Element.next(tr);
29 tr.toggleClassName('open');
29 tr.toggleClassName('open');
30 while (n != undefined && !n.hasClassName('group')) {
30 while (n != undefined && !n.hasClassName('group')) {
31 Element.toggle(n);
31 Element.toggle(n);
32 n = Element.next(n);
32 n = Element.next(n);
33 }
33 }
34 }
34 }
35
35
36 function toggleFieldset(el) {
36 function toggleFieldset(el) {
37 var fieldset = Element.up(el, 'fieldset');
37 var fieldset = Element.up(el, 'fieldset');
38 fieldset.toggleClassName('collapsed');
38 fieldset.toggleClassName('collapsed');
39 Effect.toggle(fieldset.down('div'), 'slide', {duration:0.2});
39 Effect.toggle(fieldset.down('div'), 'slide', {duration:0.2});
40 }
40 }
41
41
42 var fileFieldCount = 1;
42 var fileFieldCount = 1;
43
43
44 function addFileField() {
44 function addFileField() {
45 if (fileFieldCount >= 10) return false
45 if (fileFieldCount >= 10) return false
46 fileFieldCount++;
46 fileFieldCount++;
47 var f = document.createElement("input");
47 var f = document.createElement("input");
48 f.type = "file";
48 f.type = "file";
49 f.name = "attachments[" + fileFieldCount + "][file]";
49 f.name = "attachments[" + fileFieldCount + "][file]";
50 f.size = 30;
50 f.size = 30;
51 var d = document.createElement("input");
51 var d = document.createElement("input");
52 d.type = "text";
52 d.type = "text";
53 d.name = "attachments[" + fileFieldCount + "][description]";
53 d.name = "attachments[" + fileFieldCount + "][description]";
54 d.size = 60;
54 d.size = 60;
55
55
56 p = document.getElementById("attachments_fields");
56 p = document.getElementById("attachments_fields");
57 p.appendChild(document.createElement("br"));
57 p.appendChild(document.createElement("br"));
58 p.appendChild(f);
58 p.appendChild(f);
59 p.appendChild(d);
59 p.appendChild(d);
60 }
60 }
61
61
62 function showTab(name) {
62 function showTab(name) {
63 var f = $$('div#content .tab-content');
63 var f = $$('div#content .tab-content');
64 for(var i=0; i<f.length; i++){
64 for(var i=0; i<f.length; i++){
65 Element.hide(f[i]);
65 Element.hide(f[i]);
66 }
66 }
67 var f = $$('div.tabs a');
67 var f = $$('div.tabs a');
68 for(var i=0; i<f.length; i++){
68 for(var i=0; i<f.length; i++){
69 Element.removeClassName(f[i], "selected");
69 Element.removeClassName(f[i], "selected");
70 }
70 }
71 Element.show('tab-content-' + name);
71 Element.show('tab-content-' + name);
72 Element.addClassName('tab-' + name, "selected");
72 Element.addClassName('tab-' + name, "selected");
73 return false;
73 return false;
74 }
74 }
75
75
76 function moveTabRight(el) {
76 function moveTabRight(el) {
77 var lis = Element.up(el, 'div.tabs').down('ul').childElements();
77 var lis = Element.up(el, 'div.tabs').down('ul').childElements();
78 var tabsWidth = 0;
78 var tabsWidth = 0;
79 var i;
79 var i;
80 for (i=0; i<lis.length; i++) {
80 for (i=0; i<lis.length; i++) {
81 if (lis[i].visible()) {
81 if (lis[i].visible()) {
82 tabsWidth += lis[i].getWidth() + 6;
82 tabsWidth += lis[i].getWidth() + 6;
83 }
83 }
84 }
84 }
85 if (tabsWidth < Element.up(el, 'div.tabs').getWidth() - 60) {
85 if (tabsWidth < Element.up(el, 'div.tabs').getWidth() - 60) {
86 return;
86 return;
87 }
87 }
88 i=0;
88 i=0;
89 while (i<lis.length && !lis[i].visible()) {
89 while (i<lis.length && !lis[i].visible()) {
90 i++;
90 i++;
91 }
91 }
92 lis[i].hide();
92 lis[i].hide();
93 }
93 }
94
94
95 function moveTabLeft(el) {
95 function moveTabLeft(el) {
96 var lis = Element.up(el, 'div.tabs').down('ul').childElements();
96 var lis = Element.up(el, 'div.tabs').down('ul').childElements();
97 var i = 0;
97 var i = 0;
98 while (i<lis.length && !lis[i].visible()) {
98 while (i<lis.length && !lis[i].visible()) {
99 i++;
99 i++;
100 }
100 }
101 if (i>0) {
101 if (i>0) {
102 lis[i-1].show();
102 lis[i-1].show();
103 }
103 }
104 }
104 }
105
105
106 function displayTabsButtons() {
106 function displayTabsButtons() {
107 var lis;
107 var lis;
108 var tabsWidth = 0;
108 var tabsWidth = 0;
109 var i;
109 var i;
110 $$('div.tabs').each(function(el) {
110 $$('div.tabs').each(function(el) {
111 lis = el.down('ul').childElements();
111 lis = el.down('ul').childElements();
112 for (i=0; i<lis.length; i++) {
112 for (i=0; i<lis.length; i++) {
113 if (lis[i].visible()) {
113 if (lis[i].visible()) {
114 tabsWidth += lis[i].getWidth() + 6;
114 tabsWidth += lis[i].getWidth() + 6;
115 }
115 }
116 }
116 }
117 if ((tabsWidth < el.getWidth() - 60) && (lis[0].visible())) {
117 if ((tabsWidth < el.getWidth() - 60) && (lis[0].visible())) {
118 el.down('div.tabs-buttons').hide();
118 el.down('div.tabs-buttons').hide();
119 } else {
119 } else {
120 el.down('div.tabs-buttons').show();
120 el.down('div.tabs-buttons').show();
121 }
121 }
122 });
122 });
123 }
123 }
124
124
125 function setPredecessorFieldsVisibility() {
125 function setPredecessorFieldsVisibility() {
126 relationType = $('relation_relation_type');
126 relationType = $('relation_relation_type');
127 if (relationType && (relationType.value == "precedes" || relationType.value == "follows")) {
127 if (relationType && (relationType.value == "precedes" || relationType.value == "follows")) {
128 Element.show('predecessor_fields');
128 Element.show('predecessor_fields');
129 } else {
129 } else {
130 Element.hide('predecessor_fields');
130 Element.hide('predecessor_fields');
131 }
131 }
132 }
132 }
133
133
134 function promptToRemote(text, param, url) {
134 function promptToRemote(text, param, url) {
135 value = prompt(text + ':');
135 value = prompt(text + ':');
136 if (value) {
136 if (value) {
137 new Ajax.Request(url + '?' + param + '=' + encodeURIComponent(value), {asynchronous:true, evalScripts:true});
137 new Ajax.Request(url + '?' + param + '=' + encodeURIComponent(value), {asynchronous:true, evalScripts:true});
138 return false;
138 return false;
139 }
139 }
140 }
140 }
141
141
142 function collapseScmEntry(id) {
142 function collapseScmEntry(id) {
143 var els = document.getElementsByClassName(id, 'browser');
143 var els = document.getElementsByClassName(id, 'browser');
144 for (var i = 0; i < els.length; i++) {
144 for (var i = 0; i < els.length; i++) {
145 if (els[i].hasClassName('open')) {
145 if (els[i].hasClassName('open')) {
146 collapseScmEntry(els[i].id);
146 collapseScmEntry(els[i].id);
147 }
147 }
148 Element.hide(els[i]);
148 Element.hide(els[i]);
149 }
149 }
150 $(id).removeClassName('open');
150 $(id).removeClassName('open');
151 }
151 }
152
152
153 function expandScmEntry(id) {
153 function expandScmEntry(id) {
154 var els = document.getElementsByClassName(id, 'browser');
154 var els = document.getElementsByClassName(id, 'browser');
155 for (var i = 0; i < els.length; i++) {
155 for (var i = 0; i < els.length; i++) {
156 Element.show(els[i]);
156 Element.show(els[i]);
157 if (els[i].hasClassName('loaded') && !els[i].hasClassName('collapsed')) {
157 if (els[i].hasClassName('loaded') && !els[i].hasClassName('collapsed')) {
158 expandScmEntry(els[i].id);
158 expandScmEntry(els[i].id);
159 }
159 }
160 }
160 }
161 $(id).addClassName('open');
161 $(id).addClassName('open');
162 }
162 }
163
163
164 function scmEntryClick(id) {
164 function scmEntryClick(id) {
165 el = $(id);
165 el = $(id);
166 if (el.hasClassName('open')) {
166 if (el.hasClassName('open')) {
167 collapseScmEntry(id);
167 collapseScmEntry(id);
168 el.addClassName('collapsed');
168 el.addClassName('collapsed');
169 return false;
169 return false;
170 } else if (el.hasClassName('loaded')) {
170 } else if (el.hasClassName('loaded')) {
171 expandScmEntry(id);
171 expandScmEntry(id);
172 el.removeClassName('collapsed');
172 el.removeClassName('collapsed');
173 return false;
173 return false;
174 }
174 }
175 if (el.hasClassName('loading')) {
175 if (el.hasClassName('loading')) {
176 return false;
176 return false;
177 }
177 }
178 el.addClassName('loading');
178 el.addClassName('loading');
179 return true;
179 return true;
180 }
180 }
181
181
182 function scmEntryLoaded(id) {
182 function scmEntryLoaded(id) {
183 Element.addClassName(id, 'open');
183 Element.addClassName(id, 'open');
184 Element.addClassName(id, 'loaded');
184 Element.addClassName(id, 'loaded');
185 Element.removeClassName(id, 'loading');
185 Element.removeClassName(id, 'loading');
186 }
186 }
187
187
188 function randomKey(size) {
188 function randomKey(size) {
189 var chars = new Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z');
189 var chars = new Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z');
190 var key = '';
190 var key = '';
191 for (i = 0; i < size; i++) {
191 for (i = 0; i < size; i++) {
192 key += chars[Math.floor(Math.random() * chars.length)];
192 key += chars[Math.floor(Math.random() * chars.length)];
193 }
193 }
194 return key;
194 return key;
195 }
195 }
196
196
197 /* shows and hides ajax indicator */
197 /* shows and hides ajax indicator */
198 Ajax.Responders.register({
198 Ajax.Responders.register({
199 onCreate: function(){
199 onCreate: function(){
200 if ($('ajax-indicator') && Ajax.activeRequestCount > 0) {
200 if ($('ajax-indicator') && Ajax.activeRequestCount > 0) {
201 Element.show('ajax-indicator');
201 Element.show('ajax-indicator');
202 }
202 }
203 },
203 },
204 onComplete: function(){
204 onComplete: function(){
205 if ($('ajax-indicator') && Ajax.activeRequestCount == 0) {
205 if ($('ajax-indicator') && Ajax.activeRequestCount == 0) {
206 Element.hide('ajax-indicator');
206 Element.hide('ajax-indicator');
207 }
207 }
208 }
208 }
209 });
209 });
210
211 Event.observe(window, 'load', function() {
212 $$('.hol').each(function(el) {
213 el.hide();
214 });
215 });
General Comments 0
You need to be logged in to leave comments. Login now