Feature #5577 » category_watchers_patch-20120202-trunk_r8748.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 |
respond_to do |format| |
| 41 | 51 |
format.js do |
| app/views/issues/new.html.erb (working copy) | ||
|---|---|---|
| 23 | 23 |
<% if @issue.safe_attribute? 'watcher_user_ids' -%> |
| 24 | 24 |
<p id="watchers_form"><label><%= l(:label_issue_watchers) %></label> |
| 25 | 25 |
<% @issue.project.users.sort.each do |user| -%> |
| 26 |
<label class="floating"><%= check_box_tag 'issue[watcher_user_ids][]', user.id, @issue.watched_by?(user), :id => nil %> <%=h user %></label> |
|
| 26 |
<label class="floating watchers_label"><%= check_box_tag 'issue[watcher_user_ids][]', user.id, @issue.watched_by?(user), :id => nil %> <%=h user %></label>
|
|
| 27 | 27 |
<% end -%> |
| 28 | 28 |
</p> |
| 29 |
<%= javascript_tag "setupNewIssueWatchersByCategory('#{j(url_for :controller => 'watchers', :action => 'show', :watchable_type => 'issue_category', :watchable_id => 'watchable_id', :format => 'json')}')" %>
|
|
| 29 | 30 |
<% end %> |
| 30 | 31 |
</div> |
| 31 | 32 | |
| app/views/issue_categories/_form.html.erb (working copy) | ||
|---|---|---|
| 3 | 3 |
<div class="box tabular"> |
| 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) | ||
|---|---|---|
| 515 | 515 |
} |
| 516 | 516 | |
| 517 | 517 |
Event.observe(window, 'load', hideOnLoad); |
| 518 | ||
| 519 |
function setupNewIssueWatchersByCategory(url_pattern) {
|
|
| 520 |
issue_category_id = $('issue_category_id');
|
|
| 521 |
if (!issue_category_id) {
|
|
| 522 |
return; |
|
| 523 |
} |
|
| 524 |
function reset() {
|
|
| 525 |
$$('#watchers_form .watchers_default input').each(function(el){
|
|
| 526 |
el.checked = false; |
|
| 527 |
el.parentNode.removeClassName('watchers_default');
|
|
| 528 |
}); |
|
| 529 |
} |
|
| 530 |
function f() {
|
|
| 531 |
if (0 < issue_category_id.value.length) {
|
|
| 532 |
url = url_pattern.replace(/watchable_id/, issue_category_id.value); |
|
| 533 |
new Ajax.Request(url, {
|
|
| 534 |
onSuccess: function (request) {
|
|
| 535 |
eval("result="+ request.responseText);
|
|
| 536 |
reset(); |
|
| 537 |
$$('#watchers_form .watchers_label input').each(function(el){
|
|
| 538 |
user_id = parseInt(el.value); |
|
| 539 |
result.each(function(watcher){
|
|
| 540 |
if (user_id === watcher.user_id) {
|
|
| 541 |
el.checked = true; |
|
| 542 |
el.parentNode.addClassName('watchers_default');
|
|
| 543 |
throw $break; |
|
| 544 |
} |
|
| 545 |
}); |
|
| 546 |
}); |
|
| 547 |
} |
|
| 548 |
}); |
|
| 549 |
} else {
|
|
| 550 |
reset(); |
|
| 551 |
} |
|
| 552 |
} |
|
| 553 |
Event.observe(issue_category_id, 'change', f); |
|
| 554 |
f(); |
|
| 555 |
} |
|
| public/stylesheets/application.css (working copy) | ||
|---|---|---|
| 1048 | 1048 |
height:1px; |
| 1049 | 1049 |
overflow:hidden; |
| 1050 | 1050 |
} |
| 1051 | ||
| 1052 |
#watchers_form .watchers_default {
|
|
| 1053 |
color: #080; |
|
| 1054 |
font-weight:bold; |
|
| 1055 |
} |
|
| config/locales/en.yml (working copy) | ||
|---|---|---|
| 496 | 496 |
label_issue_category: Issue category |
| 497 | 497 |
label_issue_category_plural: Issue categories |
| 498 | 498 |
label_issue_category_new: New category |
| 499 |
label_issue_category_watchers: Default watchers |
|
| 499 | 500 |
label_custom_field: Custom field |
| 500 | 501 |
label_custom_field_plural: Custom fields |
| 501 | 502 |
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) | ||
|---|---|---|
| 140 | 140 |
map.connect 'watchers/autocomplete_for_user', :controller=> 'watchers', :action => 'autocomplete_for_user', |
| 141 | 141 |
:conditions => {:method => :get}
|
| 142 | 142 | |
| 143 |
map.connect 'watchers/:action/:watchable_type/:watchable_id.:format', :controller => 'watchers' |
|
| 144 | ||
| 143 | 145 |
# TODO: port to be part of the resources route(s) |
| 144 | 146 |
map.with_options :conditions => {:method => :get} do |project_views|
|
| 145 | 147 |
project_views.connect 'projects/:id/settings/:tab', |