Feature #5577 » category_watchers_patch-20120202-tags_1.3.0.patch
| app/models/issue_category.rb (working copy) | ||
|---|---|---|
| 20 | 20 |
belongs_to :assigned_to, :class_name => 'Principal', :foreign_key => 'assigned_to_id' |
| 21 | 21 |
has_many :issues, :foreign_key => 'category_id', :dependent => :nullify |
| 22 | 22 | |
| 23 |
acts_as_watchable |
|
| 24 | ||
| 23 | 25 |
validates_presence_of :name |
| 24 | 26 |
validates_uniqueness_of :name, :scope => [:project_id] |
| 25 | 27 |
validates_length_of :name, :maximum => 30 |
| app/controllers/issue_categories_controller.rb (working copy) | ||
|---|---|---|
| 40 | 40 | |
| 41 | 41 |
def new |
| 42 | 42 |
@category = @project.issue_categories.build(params[:issue_category]) |
| 43 |
assign_watchers_from_params |
|
| 43 | 44 |
end |
| 44 | 45 | |
| 45 | 46 |
verify :method => :post, :only => :create |
| 46 | 47 |
def create |
| 47 | 48 |
@category = @project.issue_categories.build(params[:issue_category]) |
| 49 |
assign_watchers_from_params |
|
| 48 | 50 |
if @category.save |
| 49 | 51 |
respond_to do |format| |
| 50 | 52 |
format.html do |
| ... | ... | |
| 75 | 77 | |
| 76 | 78 |
verify :method => :put, :only => :update |
| 77 | 79 |
def update |
| 80 |
assign_watchers_from_params |
|
| 78 | 81 |
if @category.update_attributes(params[:issue_category]) |
| 79 | 82 |
respond_to do |format| |
| 80 | 83 |
format.html {
|
| ... | ... | |
| 122 | 125 |
rescue ActiveRecord::RecordNotFound |
| 123 | 126 |
render_404 |
| 124 | 127 |
end |
| 128 | ||
| 129 |
def assign_watchers_from_params |
|
| 130 |
if params[:issue_category].is_a?(Hash) |
|
| 131 |
@category.watcher_user_ids = params[:issue_category]['watcher_user_ids'] |
|
| 132 |
end |
|
| 133 |
end |
|
| 125 | 134 |
end |
| app/controllers/watchers_controller.rb (working copy) | ||
|---|---|---|
| 16 | 16 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| 17 | 17 | |
| 18 | 18 |
class WatchersController < ApplicationController |
| 19 |
before_filter :find_project |
|
| 19 |
before_filter :find_project, :except => [:show]
|
|
| 20 | 20 |
before_filter :require_login, :check_project_privacy, :only => [:watch, :unwatch] |
| 21 | 21 |
before_filter :authorize, :only => [:new, :destroy] |
| 22 | 22 | |
| ... | ... | |
| 36 | 36 |
set_watcher(User.current, false) |
| 37 | 37 |
end |
| 38 | 38 | |
| 39 |
def show |
|
| 40 |
p params |
|
| 41 |
respond_to do |format| |
|
| 42 |
format.api {
|
|
| 43 |
result = Watcher.find(:all, :conditions => [ "watchable_type = ? and watchable_id = ?", params['watchable_type'].classify, params['watchable_id'].to_i]) |
|
| 44 |
render :json => result |
|
| 45 |
} |
|
| 46 |
end |
|
| 47 |
end |
|
| 48 | ||
| 39 | 49 |
def new |
| 40 | 50 |
@watcher = Watcher.new(params[:watcher]) |
| 41 | 51 |
@watcher.watchable = @watched |
| app/views/issues/_form.html.erb (working copy) | ||
|---|---|---|
| 30 | 30 |
<% if @issue.new_record? && User.current.allowed_to?(:add_issue_watchers, @project) -%> |
| 31 | 31 |
<p id="watchers_form"><label><%= l(:label_issue_watchers) %></label> |
| 32 | 32 |
<% @issue.project.users.sort.each do |user| -%> |
| 33 |
<label class="floating"><%= check_box_tag 'issue[watcher_user_ids][]', user.id, @issue.watched_by?(user) %> <%=h user %></label>
|
|
| 33 |
<label class="floating watchers_label"><%= check_box_tag 'issue[watcher_user_ids][]', user.id, @issue.watched_by?(user)%> <%=h user %></label>
|
|
| 34 | 34 |
<% end -%> |
| 35 | 35 |
</p> |
| 36 |
<%= javascript_tag "setupNewIssueWatchersByCategory('#{j(url_for :controller => 'watchers', :action => 'show', :watchable_type => 'issue_category', :watchable_id => 'watchable_id', :format => 'json')}')" %>
|
|
| 36 | 37 |
<% end %> |
| 37 | 38 | |
| 38 | 39 |
<%= call_hook(:view_issues_form_details_bottom, { :issue => @issue, :form => f }) %>
|
| app/views/issue_categories/_form.html.erb (working copy) | ||
|---|---|---|
| 3 | 3 |
<div class="box"> |
| 4 | 4 |
<p><%= f.text_field :name, :size => 30, :required => true %></p> |
| 5 | 5 |
<p><%= f.select :assigned_to_id, principals_options_for_select(@project.assignable_users, @category.assigned_to), :include_blank => true %></p> |
| 6 |
<p id="watchers_form"><label><%= l(:label_issue_watchers) %></label> |
|
| 7 |
<% @project.users.sort.each do |user| -%> |
|
| 8 |
<label class="floating"><%= check_box_tag 'issue_category[watcher_user_ids][]', user.id, @category.watched_by?(user) %> <%=h user %></label> |
|
| 9 |
<% end -%> |
|
| 6 | 10 |
</div> |
| public/javascripts/application.js (working copy) | ||
|---|---|---|
| 415 | 415 |
} |
| 416 | 416 | |
| 417 | 417 |
Event.observe(window, 'load', hideOnLoad); |
| 418 | ||
| 419 |
function setupNewIssueWatchersByCategory(url_pattern) {
|
|
| 420 |
issue_category_id = $('issue_category_id');
|
|
| 421 |
if (!issue_category_id) {
|
|
| 422 |
return; |
|
| 423 |
} |
|
| 424 |
function reset() {
|
|
| 425 |
$$('#watchers_form .watchers_default input').each(function(el){
|
|
| 426 |
el.checked = false; |
|
| 427 |
el.parentNode.removeClassName('watchers_default');
|
|
| 428 |
}); |
|
| 429 |
} |
|
| 430 |
function f() {
|
|
| 431 |
if (0 < issue_category_id.value.length) {
|
|
| 432 |
url = url_pattern.replace(/watchable_id/, issue_category_id.value); |
|
| 433 |
new Ajax.Request(url, {
|
|
| 434 |
onSuccess: function (request) {
|
|
| 435 |
eval("result="+ request.responseText);
|
|
| 436 |
reset(); |
|
| 437 |
$$('#watchers_form .watchers_label input').each(function(el){
|
|
| 438 |
user_id = parseInt(el.value); |
|
| 439 |
result.each(function(watcher){
|
|
| 440 |
if (user_id === watcher.user_id) {
|
|
| 441 |
el.checked = true; |
|
| 442 |
el.parentNode.addClassName('watchers_default');
|
|
| 443 |
throw $break; |
|
| 444 |
} |
|
| 445 |
}); |
|
| 446 |
}); |
|
| 447 |
} |
|
| 448 |
}); |
|
| 449 |
} else {
|
|
| 450 |
reset(); |
|
| 451 |
} |
|
| 452 |
} |
|
| 453 |
Event.observe(issue_category_id, 'change', f); |
|
| 454 |
f(); |
|
| 455 |
} |
|
| public/stylesheets/application.css (working copy) | ||
|---|---|---|
| 1018 | 1018 |
height:1px; |
| 1019 | 1019 |
overflow:hidden; |
| 1020 | 1020 |
} |
| 1021 | ||
| 1022 |
#watchers_form .watchers_default {
|
|
| 1023 |
color: #080; |
|
| 1024 |
font-weight:bold; |
|
| 1025 |
} |
|
| config/locales/en.yml (working copy) | ||
|---|---|---|
| 493 | 493 |
label_issue_category: Issue category |
| 494 | 494 |
label_issue_category_plural: Issue categories |
| 495 | 495 |
label_issue_category_new: New category |
| 496 |
label_issue_category_watchers: Default watchers |
|
| 496 | 497 |
label_custom_field: Custom field |
| 497 | 498 |
label_custom_field_plural: Custom fields |
| 498 | 499 |
label_custom_field_new: New custom field |
| config/locales/ja.yml (working copy) | ||
|---|---|---|
| 510 | 510 |
label_issue_category: チケットのカテゴリ |
| 511 | 511 |
label_issue_category_plural: チケットのカテゴリ |
| 512 | 512 |
label_issue_category_new: 新しいカテゴリ |
| 513 |
label_issue_category_watchers: デフォルトウォッチャー |
|
| 513 | 514 |
label_custom_field: カスタムフィールド |
| 514 | 515 |
label_custom_field_plural: カスタムフィールド |
| 515 | 516 |
label_custom_field_new: 新しいカスタムフィールドを作成 |
| config/routes.rb (working copy) | ||
|---|---|---|
| 180 | 180 |
# Destroy uses a get request to prompt the user before the actual DELETE request |
| 181 | 181 |
map.project_destroy_confirm 'projects/:id/destroy', :controller => 'projects', :action => 'destroy', :conditions => {:method => :get}
|
| 182 | 182 | |
| 183 |
map.connect 'watchers/:action/:watchable_type/:watchable_id.:format', :controller => 'watchers' |
|
| 184 | ||
| 183 | 185 |
# TODO: port to be part of the resources route(s) |
| 184 | 186 |
map.with_options :controller => 'projects' do |project_mapper| |
| 185 | 187 |
project_mapper.with_options :conditions => {:method => :get} do |project_views|
|