##// END OF EJS Templates
Hide the role forms when editing or adding Project members. #5452...
Eric Davis -
r3670:2562bc5bcd0c
parent child
Show More
@@ -1,94 +1,100
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 class MembersController < ApplicationController
18 class MembersController < ApplicationController
19 model_object Member
19 model_object Member
20 before_filter :find_model_object, :except => [:new, :autocomplete_for_member]
20 before_filter :find_model_object, :except => [:new, :autocomplete_for_member]
21 before_filter :find_project_from_association, :except => [:new, :autocomplete_for_member]
21 before_filter :find_project_from_association, :except => [:new, :autocomplete_for_member]
22 before_filter :find_project, :only => [:new, :autocomplete_for_member]
22 before_filter :find_project, :only => [:new, :autocomplete_for_member]
23 before_filter :authorize
23 before_filter :authorize
24
24
25 def new
25 def new
26 members = []
26 members = []
27 if params[:member] && request.post?
27 if params[:member] && request.post?
28 attrs = params[:member].dup
28 attrs = params[:member].dup
29 if (user_ids = attrs.delete(:user_ids))
29 if (user_ids = attrs.delete(:user_ids))
30 user_ids.each do |user_id|
30 user_ids.each do |user_id|
31 members << Member.new(attrs.merge(:user_id => user_id))
31 members << Member.new(attrs.merge(:user_id => user_id))
32 end
32 end
33 else
33 else
34 members << Member.new(attrs)
34 members << Member.new(attrs)
35 end
35 end
36 @project.members << members
36 @project.members << members
37 end
37 end
38 respond_to do |format|
38 respond_to do |format|
39 if members.present? && members.all? {|m| m.valid? }
39 if members.present? && members.all? {|m| m.valid? }
40
40
41 format.html { redirect_to :controller => 'projects', :action => 'settings', :tab => 'members', :id => @project }
41 format.html { redirect_to :controller => 'projects', :action => 'settings', :tab => 'members', :id => @project }
42
42
43 format.js {
43 format.js {
44 render(:update) {|page|
44 render(:update) {|page|
45 page.replace_html "tab-content-members", :partial => 'projects/settings/members'
45 page.replace_html "tab-content-members", :partial => 'projects/settings/members'
46 page << 'hideOnLoad()'
46 members.each {|member| page.visual_effect(:highlight, "member-#{member.id}") }
47 members.each {|member| page.visual_effect(:highlight, "member-#{member.id}") }
47 }
48 }
48 }
49 }
49 else
50 else
50
51
51 format.js {
52 format.js {
52 render(:update) {|page|
53 render(:update) {|page|
53 errors = members.collect {|m|
54 errors = members.collect {|m|
54 m.errors.full_messages
55 m.errors.full_messages
55 }.flatten.uniq
56 }.flatten.uniq
56
57
57 page.alert(l(:notice_failed_to_save_members, :errors => errors.join(', ')))
58 page.alert(l(:notice_failed_to_save_members, :errors => errors.join(', ')))
58 }
59 }
59 }
60 }
60
61
61 end
62 end
62 end
63 end
63 end
64 end
64
65
65 def edit
66 def edit
66 if request.post? and @member.update_attributes(params[:member])
67 if request.post? and @member.update_attributes(params[:member])
67 respond_to do |format|
68 respond_to do |format|
68 format.html { redirect_to :controller => 'projects', :action => 'settings', :tab => 'members', :id => @project }
69 format.html { redirect_to :controller => 'projects', :action => 'settings', :tab => 'members', :id => @project }
69 format.js {
70 format.js {
70 render(:update) {|page|
71 render(:update) {|page|
71 page.replace_html "tab-content-members", :partial => 'projects/settings/members'
72 page.replace_html "tab-content-members", :partial => 'projects/settings/members'
73 page << 'hideOnLoad()'
72 page.visual_effect(:highlight, "member-#{@member.id}")
74 page.visual_effect(:highlight, "member-#{@member.id}")
73 }
75 }
74 }
76 }
75 end
77 end
76 end
78 end
77 end
79 end
78
80
79 def destroy
81 def destroy
80 if request.post? && @member.deletable?
82 if request.post? && @member.deletable?
81 @member.destroy
83 @member.destroy
82 end
84 end
83 respond_to do |format|
85 respond_to do |format|
84 format.html { redirect_to :controller => 'projects', :action => 'settings', :tab => 'members', :id => @project }
86 format.html { redirect_to :controller => 'projects', :action => 'settings', :tab => 'members', :id => @project }
85 format.js { render(:update) {|page| page.replace_html "tab-content-members", :partial => 'projects/settings/members'} }
87 format.js { render(:update) {|page|
88 page.replace_html "tab-content-members", :partial => 'projects/settings/members'
89 page << 'hideOnLoad()'
90 }
91 }
86 end
92 end
87 end
93 end
88
94
89 def autocomplete_for_member
95 def autocomplete_for_member
90 @principals = Principal.active.like(params[:q]).find(:all, :limit => 100) - @project.principals
96 @principals = Principal.active.like(params[:q]).find(:all, :limit => 100) - @project.principals
91 render :layout => false
97 render :layout => false
92 end
98 end
93
99
94 end
100 end
@@ -1,233 +1,235
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 var dLabel = document.createElement("label");
55 var dLabel = document.createElement("label");
56 dLabel.addClassName('inline');
56 dLabel.addClassName('inline');
57 // Pulls the languge value used for Optional Description
57 // Pulls the languge value used for Optional Description
58 dLabel.update($('attachment_description_label_content').innerHTML)
58 dLabel.update($('attachment_description_label_content').innerHTML)
59
59
60 p = document.getElementById("attachments_fields");
60 p = document.getElementById("attachments_fields");
61 p.appendChild(document.createElement("br"));
61 p.appendChild(document.createElement("br"));
62 p.appendChild(f);
62 p.appendChild(f);
63 p.appendChild(dLabel);
63 p.appendChild(dLabel);
64 dLabel.appendChild(d);
64 dLabel.appendChild(d);
65
65
66 }
66 }
67
67
68 function showTab(name) {
68 function showTab(name) {
69 var f = $$('div#content .tab-content');
69 var f = $$('div#content .tab-content');
70 for(var i=0; i<f.length; i++){
70 for(var i=0; i<f.length; i++){
71 Element.hide(f[i]);
71 Element.hide(f[i]);
72 }
72 }
73 var f = $$('div.tabs a');
73 var f = $$('div.tabs a');
74 for(var i=0; i<f.length; i++){
74 for(var i=0; i<f.length; i++){
75 Element.removeClassName(f[i], "selected");
75 Element.removeClassName(f[i], "selected");
76 }
76 }
77 Element.show('tab-content-' + name);
77 Element.show('tab-content-' + name);
78 Element.addClassName('tab-' + name, "selected");
78 Element.addClassName('tab-' + name, "selected");
79 return false;
79 return false;
80 }
80 }
81
81
82 function moveTabRight(el) {
82 function moveTabRight(el) {
83 var lis = Element.up(el, 'div.tabs').down('ul').childElements();
83 var lis = Element.up(el, 'div.tabs').down('ul').childElements();
84 var tabsWidth = 0;
84 var tabsWidth = 0;
85 var i;
85 var i;
86 for (i=0; i<lis.length; i++) {
86 for (i=0; i<lis.length; i++) {
87 if (lis[i].visible()) {
87 if (lis[i].visible()) {
88 tabsWidth += lis[i].getWidth() + 6;
88 tabsWidth += lis[i].getWidth() + 6;
89 }
89 }
90 }
90 }
91 if (tabsWidth < Element.up(el, 'div.tabs').getWidth() - 60) {
91 if (tabsWidth < Element.up(el, 'div.tabs').getWidth() - 60) {
92 return;
92 return;
93 }
93 }
94 i=0;
94 i=0;
95 while (i<lis.length && !lis[i].visible()) {
95 while (i<lis.length && !lis[i].visible()) {
96 i++;
96 i++;
97 }
97 }
98 lis[i].hide();
98 lis[i].hide();
99 }
99 }
100
100
101 function moveTabLeft(el) {
101 function moveTabLeft(el) {
102 var lis = Element.up(el, 'div.tabs').down('ul').childElements();
102 var lis = Element.up(el, 'div.tabs').down('ul').childElements();
103 var i = 0;
103 var i = 0;
104 while (i<lis.length && !lis[i].visible()) {
104 while (i<lis.length && !lis[i].visible()) {
105 i++;
105 i++;
106 }
106 }
107 if (i>0) {
107 if (i>0) {
108 lis[i-1].show();
108 lis[i-1].show();
109 }
109 }
110 }
110 }
111
111
112 function displayTabsButtons() {
112 function displayTabsButtons() {
113 var lis;
113 var lis;
114 var tabsWidth = 0;
114 var tabsWidth = 0;
115 var i;
115 var i;
116 $$('div.tabs').each(function(el) {
116 $$('div.tabs').each(function(el) {
117 lis = el.down('ul').childElements();
117 lis = el.down('ul').childElements();
118 for (i=0; i<lis.length; i++) {
118 for (i=0; i<lis.length; i++) {
119 if (lis[i].visible()) {
119 if (lis[i].visible()) {
120 tabsWidth += lis[i].getWidth() + 6;
120 tabsWidth += lis[i].getWidth() + 6;
121 }
121 }
122 }
122 }
123 if ((tabsWidth < el.getWidth() - 60) && (lis[0].visible())) {
123 if ((tabsWidth < el.getWidth() - 60) && (lis[0].visible())) {
124 el.down('div.tabs-buttons').hide();
124 el.down('div.tabs-buttons').hide();
125 } else {
125 } else {
126 el.down('div.tabs-buttons').show();
126 el.down('div.tabs-buttons').show();
127 }
127 }
128 });
128 });
129 }
129 }
130
130
131 function setPredecessorFieldsVisibility() {
131 function setPredecessorFieldsVisibility() {
132 relationType = $('relation_relation_type');
132 relationType = $('relation_relation_type');
133 if (relationType && (relationType.value == "precedes" || relationType.value == "follows")) {
133 if (relationType && (relationType.value == "precedes" || relationType.value == "follows")) {
134 Element.show('predecessor_fields');
134 Element.show('predecessor_fields');
135 } else {
135 } else {
136 Element.hide('predecessor_fields');
136 Element.hide('predecessor_fields');
137 }
137 }
138 }
138 }
139
139
140 function promptToRemote(text, param, url) {
140 function promptToRemote(text, param, url) {
141 value = prompt(text + ':');
141 value = prompt(text + ':');
142 if (value) {
142 if (value) {
143 new Ajax.Request(url + '?' + param + '=' + encodeURIComponent(value), {asynchronous:true, evalScripts:true});
143 new Ajax.Request(url + '?' + param + '=' + encodeURIComponent(value), {asynchronous:true, evalScripts:true});
144 return false;
144 return false;
145 }
145 }
146 }
146 }
147
147
148 function collapseScmEntry(id) {
148 function collapseScmEntry(id) {
149 var els = document.getElementsByClassName(id, 'browser');
149 var els = document.getElementsByClassName(id, 'browser');
150 for (var i = 0; i < els.length; i++) {
150 for (var i = 0; i < els.length; i++) {
151 if (els[i].hasClassName('open')) {
151 if (els[i].hasClassName('open')) {
152 collapseScmEntry(els[i].id);
152 collapseScmEntry(els[i].id);
153 }
153 }
154 Element.hide(els[i]);
154 Element.hide(els[i]);
155 }
155 }
156 $(id).removeClassName('open');
156 $(id).removeClassName('open');
157 }
157 }
158
158
159 function expandScmEntry(id) {
159 function expandScmEntry(id) {
160 var els = document.getElementsByClassName(id, 'browser');
160 var els = document.getElementsByClassName(id, 'browser');
161 for (var i = 0; i < els.length; i++) {
161 for (var i = 0; i < els.length; i++) {
162 Element.show(els[i]);
162 Element.show(els[i]);
163 if (els[i].hasClassName('loaded') && !els[i].hasClassName('collapsed')) {
163 if (els[i].hasClassName('loaded') && !els[i].hasClassName('collapsed')) {
164 expandScmEntry(els[i].id);
164 expandScmEntry(els[i].id);
165 }
165 }
166 }
166 }
167 $(id).addClassName('open');
167 $(id).addClassName('open');
168 }
168 }
169
169
170 function scmEntryClick(id) {
170 function scmEntryClick(id) {
171 el = $(id);
171 el = $(id);
172 if (el.hasClassName('open')) {
172 if (el.hasClassName('open')) {
173 collapseScmEntry(id);
173 collapseScmEntry(id);
174 el.addClassName('collapsed');
174 el.addClassName('collapsed');
175 return false;
175 return false;
176 } else if (el.hasClassName('loaded')) {
176 } else if (el.hasClassName('loaded')) {
177 expandScmEntry(id);
177 expandScmEntry(id);
178 el.removeClassName('collapsed');
178 el.removeClassName('collapsed');
179 return false;
179 return false;
180 }
180 }
181 if (el.hasClassName('loading')) {
181 if (el.hasClassName('loading')) {
182 return false;
182 return false;
183 }
183 }
184 el.addClassName('loading');
184 el.addClassName('loading');
185 return true;
185 return true;
186 }
186 }
187
187
188 function scmEntryLoaded(id) {
188 function scmEntryLoaded(id) {
189 Element.addClassName(id, 'open');
189 Element.addClassName(id, 'open');
190 Element.addClassName(id, 'loaded');
190 Element.addClassName(id, 'loaded');
191 Element.removeClassName(id, 'loading');
191 Element.removeClassName(id, 'loading');
192 }
192 }
193
193
194 function randomKey(size) {
194 function randomKey(size) {
195 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');
195 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');
196 var key = '';
196 var key = '';
197 for (i = 0; i < size; i++) {
197 for (i = 0; i < size; i++) {
198 key += chars[Math.floor(Math.random() * chars.length)];
198 key += chars[Math.floor(Math.random() * chars.length)];
199 }
199 }
200 return key;
200 return key;
201 }
201 }
202
202
203 function observeParentIssueField(url) {
203 function observeParentIssueField(url) {
204 new Ajax.Autocompleter('issue_parent_issue_id',
204 new Ajax.Autocompleter('issue_parent_issue_id',
205 'parent_issue_candidates',
205 'parent_issue_candidates',
206 url,
206 url,
207 { minChars: 3,
207 { minChars: 3,
208 frequency: 0.5,
208 frequency: 0.5,
209 paramName: 'q',
209 paramName: 'q',
210 updateElement: function(value) {
210 updateElement: function(value) {
211 document.getElementById('issue_parent_issue_id').value = value.id;
211 document.getElementById('issue_parent_issue_id').value = value.id;
212 }});
212 }});
213 }
213 }
214
214
215 /* shows and hides ajax indicator */
215 /* shows and hides ajax indicator */
216 Ajax.Responders.register({
216 Ajax.Responders.register({
217 onCreate: function(){
217 onCreate: function(){
218 if ($('ajax-indicator') && Ajax.activeRequestCount > 0) {
218 if ($('ajax-indicator') && Ajax.activeRequestCount > 0) {
219 Element.show('ajax-indicator');
219 Element.show('ajax-indicator');
220 }
220 }
221 },
221 },
222 onComplete: function(){
222 onComplete: function(){
223 if ($('ajax-indicator') && Ajax.activeRequestCount == 0) {
223 if ($('ajax-indicator') && Ajax.activeRequestCount == 0) {
224 Element.hide('ajax-indicator');
224 Element.hide('ajax-indicator');
225 }
225 }
226 }
226 }
227 });
227 });
228
228
229 Event.observe(window, 'load', function() {
229 function hideOnLoad() {
230 $$('.hol').each(function(el) {
230 $$('.hol').each(function(el) {
231 el.hide();
231 el.hide();
232 });
232 });
233 });
233 }
234
235 Event.observe(window, 'load', hideOnLoad);
General Comments 0
You need to be logged in to leave comments. Login now