summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/controllers/watchers_controller.rb26
-rw-r--r--app/views/layouts/base.html.erb1
-rw-r--r--app/views/watchers/_new.html.erb30
-rw-r--r--app/views/watchers/_watchers.html.erb20
-rw-r--r--app/views/watchers/autocomplete_for_user.html.erb1
-rw-r--r--config/routes.rb6
-rw-r--r--public/stylesheets/application.css3
-rw-r--r--test/functional/watchers_controller_test.rb24
-rw-r--r--test/integration/routing/watchers_test.rb18
9 files changed, 101 insertions, 28 deletions
diff --git a/app/controllers/watchers_controller.rb b/app/controllers/watchers_controller.rb
index 8c951ad9d..1a1935d0d 100644
--- a/app/controllers/watchers_controller.rb
+++ b/app/controllers/watchers_controller.rb
@@ -37,13 +37,28 @@ class WatchersController < ApplicationController
end
def new
- @watcher = Watcher.new(params[:watcher])
- @watcher.watchable = @watched
- @watcher.save if request.post?
+ respond_to do |format|
+ format.js do
+ render :update do |page|
+ page.replace_html 'ajax-modal', :partial => 'watchers/new', :locals => {:watched => @watched}
+ page << "showModal('ajax-modal', '400px');"
+ end
+ end
+ end
+ end
+
+ def create
+ if params[:watcher].is_a?(Hash) && request.post?
+ user_ids = params[:watcher][:user_ids] || [params[:watcher][:user_id]]
+ user_ids.each do |user_id|
+ Watcher.create(:watchable => @watched, :user_id => user_id)
+ end
+ end
respond_to do |format|
format.html { redirect_to :back }
format.js do
render :update do |page|
+ page.replace_html 'ajax-modal', :partial => 'watchers/new', :locals => {:watched => @watched}
page.replace_html 'watchers', :partial => 'watchers/watchers', :locals => {:watched => @watched}
end
end
@@ -64,6 +79,11 @@ class WatchersController < ApplicationController
end
end
+ def autocomplete_for_user
+ @users = User.active.like(params[:q]).find(:all, :limit => 100) - @watched.watcher_users
+ render :layout => false
+ end
+
private
def find_project
klass = Object.const_get(params[:object_type].camelcase)
diff --git a/app/views/layouts/base.html.erb b/app/views/layouts/base.html.erb
index 6673b4944..ccf5dbaee 100644
--- a/app/views/layouts/base.html.erb
+++ b/app/views/layouts/base.html.erb
@@ -73,6 +73,7 @@
</div>
<div id="ajax-indicator" style="display:none;"><span><%= l(:label_loading) %></span></div>
+<div id="ajax-modal" style="display:none;"></div>
<div id="footer">
<div class="bgl"><div class="bgr">
diff --git a/app/views/watchers/_new.html.erb b/app/views/watchers/_new.html.erb
new file mode 100644
index 000000000..56a122a51
--- /dev/null
+++ b/app/views/watchers/_new.html.erb
@@ -0,0 +1,30 @@
+<h3 class="title"><%= l(:permission_add_issue_watchers) %></h3>
+
+<% form_remote_tag :url => {:controller => 'watchers',
+ :action => 'create',
+ :object_type => watched.class.name.underscore,
+ :object_id => watched},
+ :method => :post,
+ :html => {:id => 'new-watcher-form'} do %>
+
+ <p><%= label_tag 'user_search', l(:label_user_search) %><%= text_field_tag 'user_search', nil %></p>
+ <%= observe_field(:user_search,
+ :frequency => 0.5,
+ :update => :users_for_watcher,
+ :method => :get,
+ :url => {
+ :controller => 'watchers',
+ :action => 'autocomplete_for_user',
+ :object_type => watched.class.name.underscore,
+ :object_id => watched},
+ :with => 'q') %>
+
+ <div id="users_for_watcher">
+ <%= principals_check_box_tags 'watcher[user_ids][]', watched.addable_watcher_users %>
+ </div>
+
+ <p class="buttons">
+ <%= submit_tag l(:button_add), :name => nil, :onclick => "hideModal(this);" %>
+ <%= submit_tag l(:button_cancel), :name => nil, :onclick => "hideModal(this);", :type => 'button' %>
+ </p>
+<% end %>
diff --git a/app/views/watchers/_watchers.html.erb b/app/views/watchers/_watchers.html.erb
index 67e1f4fca..1f40707be 100644
--- a/app/views/watchers/_watchers.html.erb
+++ b/app/views/watchers/_watchers.html.erb
@@ -1,26 +1,14 @@
+<% if User.current.allowed_to?(:add_issue_watchers, @project) %>
<div class="contextual">
<%= link_to_remote l(:button_add),
:url => {:controller => 'watchers',
:action => 'new',
:object_type => watched.class.name.underscore,
- :object_id => watched} if User.current.allowed_to?(:add_issue_watchers, @project) %>
+ :object_id => watched},
+ :method => 'get' %>
</div>
+<% end %>
<h3><%= l(:label_issue_watchers) %> (<%= watched.watcher_users.size %>)</h3>
-<% unless @watcher.nil? %>
- <% remote_form_for(:watcher, @watcher,
- :url => {:controller => 'watchers',
- :action => 'new',
- :object_type => watched.class.name.underscore,
- :object_id => watched},
- :method => :post,
- :html => {:id => 'new-watcher-form'}) do |f| %>
- <p><%= f.select :user_id, (watched.addable_watcher_users.collect {|m| [m.name, m.id]}), :prompt => "--- #{l(:actionview_instancetag_blank_option)} ---" %>
-
- <%= submit_tag l(:button_add) %>
- <%= toggle_link l(:button_cancel), 'new-watcher-form'%></p>
- <% end %>
-<% end %>
-
<%= watchers_list(watched) %>
diff --git a/app/views/watchers/autocomplete_for_user.html.erb b/app/views/watchers/autocomplete_for_user.html.erb
new file mode 100644
index 000000000..a24d28eb4
--- /dev/null
+++ b/app/views/watchers/autocomplete_for_user.html.erb
@@ -0,0 +1 @@
+<%= principals_check_box_tags 'watcher[user_ids][]', @users %>
diff --git a/config/routes.rb b/config/routes.rb
index cf4e34321..42e936c0f 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -128,13 +128,17 @@ ActionController::Routing::Routes.draw do |map|
:action => 'destroy', :conditions => {:method => :delete}
map.connect 'watchers/new', :controller=> 'watchers', :action => 'new',
- :conditions => {:method => [:get, :post]}
+ :conditions => {:method => :get}
+ map.connect 'watchers', :controller=> 'watchers', :action => 'create',
+ :conditions => {:method => :post}
map.connect 'watchers/destroy', :controller=> 'watchers', :action => 'destroy',
:conditions => {:method => :post}
map.connect 'watchers/watch', :controller=> 'watchers', :action => 'watch',
:conditions => {:method => :post}
map.connect 'watchers/unwatch', :controller=> 'watchers', :action => 'unwatch',
:conditions => {:method => :post}
+ map.connect 'watchers/autocomplete_for_user', :controller=> 'watchers', :action => 'autocomplete_for_user',
+ :conditions => {:method => :get}
# TODO: port to be part of the resources route(s)
map.with_options :conditions => {:method => :get} do |project_views|
diff --git a/public/stylesheets/application.css b/public/stylesheets/application.css
index ff065b85e..9c255f92e 100644
--- a/public/stylesheets/application.css
+++ b/public/stylesheets/application.css
@@ -495,6 +495,9 @@ div#tab-content-members fieldset legend, div#tab-content-memberships fieldset le
div#tab-content-members fieldset label, div#tab-content-memberships fieldset label, div#tab-content-users fieldset label { display: block; }
div#tab-content-members fieldset div, div#tab-content-users fieldset div { max-height: 400px; overflow:auto; }
+#users_for_watcher {height: 200px; overflow:auto;}
+#users_for_watcher label {display: block;}
+
table.members td.group { padding-left: 20px; background: url(../images/group.png) no-repeat 0% 50%; }
input#principal_search, input#user_search {width:100%}
diff --git a/test/functional/watchers_controller_test.rb b/test/functional/watchers_controller_test.rb
index dc9169892..c8345a833 100644
--- a/test/functional/watchers_controller_test.rb
+++ b/test/functional/watchers_controller_test.rb
@@ -67,14 +67,34 @@ class WatchersControllerTest < ActionController::TestCase
assert !Issue.find(1).watched_by?(User.find(3))
end
- def test_new_watcher
+ def test_new
+ @request.session[:user_id] = 2
+ xhr :get, :new, :object_type => 'issue', :object_id => '2'
+ assert_response :success
+ assert_select_rjs :replace_html, 'ajax-modal'
+ end
+
+ def test_create
@request.session[:user_id] = 2
assert_difference('Watcher.count') do
- xhr :post, :new, :object_type => 'issue', :object_id => '2', :watcher => {:user_id => '4'}
+ xhr :post, :create, :object_type => 'issue', :object_id => '2', :watcher => {:user_id => '4'}
+ assert_response :success
+ assert_select_rjs :replace_html, 'watchers'
+ assert_select_rjs :replace_html, 'ajax-modal'
+ end
+ assert Issue.find(2).watched_by?(User.find(4))
+ end
+
+ def test_create_multiple
+ @request.session[:user_id] = 2
+ assert_difference('Watcher.count', 2) do
+ xhr :post, :create, :object_type => 'issue', :object_id => '2', :watcher => {:user_ids => ['4', '7']}
assert_response :success
assert_select_rjs :replace_html, 'watchers'
+ assert_select_rjs :replace_html, 'ajax-modal'
end
assert Issue.find(2).watched_by?(User.find(4))
+ assert Issue.find(2).watched_by?(User.find(7))
end
def test_remove_watcher
diff --git a/test/integration/routing/watchers_test.rb b/test/integration/routing/watchers_test.rb
index 4cd12ffca..441d2533c 100644
--- a/test/integration/routing/watchers_test.rb
+++ b/test/integration/routing/watchers_test.rb
@@ -19,17 +19,23 @@ require File.expand_path('../../../test_helper', __FILE__)
class RoutingWatchersTest < ActionController::IntegrationTest
def test_watchers
- ["get", "post"].each do |method|
- assert_routing(
- { :method => method, :path => "/watchers/new" },
- { :controller => 'watchers', :action => 'new' }
- )
- end
+ assert_routing(
+ { :method => 'get', :path => "/watchers/new" },
+ { :controller => 'watchers', :action => 'new' }
+ )
+ assert_routing(
+ { :method => 'post', :path => "/watchers" },
+ { :controller => 'watchers', :action => 'create' }
+ )
assert_routing(
{ :method => 'post', :path => "/watchers/destroy" },
{ :controller => 'watchers', :action => 'destroy' }
)
assert_routing(
+ { :method => 'get', :path => "/watchers/autocomplete_for_user" },
+ { :controller => 'watchers', :action => 'autocomplete_for_user' }
+ )
+ assert_routing(
{ :method => 'post', :path => "/watchers/watch" },
{ :controller => 'watchers', :action => 'watch' }
)