@@ -0,0 +1,25 | |||||
|
1 | <div class="contextual"> | |||
|
2 | <%= link_to_remote l(:button_add), | |||
|
3 | :url => {:controller => 'watchers', | |||
|
4 | :action => 'new', | |||
|
5 | :object_type => watched.class.name.underscore, | |||
|
6 | :object_id => watched} if User.current.allowed_to?(:add_issue_watchers, @project) %> | |||
|
7 | </div> | |||
|
8 | ||||
|
9 | <p><strong><%= l(:label_issue_watchers) %></strong></p> | |||
|
10 | <%= watchers_list(watched) %> | |||
|
11 | ||||
|
12 | <% unless @watcher.nil? %> | |||
|
13 | <% remote_form_for(:watcher, @watcher, | |||
|
14 | :url => {:controller => 'watchers', | |||
|
15 | :action => 'new', | |||
|
16 | :object_type => watched.class.name.underscore, | |||
|
17 | :object_id => watched}, | |||
|
18 | :method => :post, | |||
|
19 | :html => {:id => 'new-watcher-form'}) do |f| %> | |||
|
20 | <p><%= f.select :user_id, (watched.addable_watcher_users.collect {|m| [m.name, m.id]}), :prompt => true %> | |||
|
21 | ||||
|
22 | <%= submit_tag l(:button_add) %> | |||
|
23 | <%= toggle_link l(:button_cancel), 'new-watcher-form'%></p> | |||
|
24 | <% end %> | |||
|
25 | <% end %> |
@@ -0,0 +1,6 | |||||
|
1 | --- | |||
|
2 | watchers_001: | |||
|
3 | watchable_type: Issue | |||
|
4 | watchable_id: 2 | |||
|
5 | user_id: 3 | |||
|
6 | No newline at end of file |
@@ -0,0 +1,70 | |||||
|
1 | # Redmine - project management software | |||
|
2 | # Copyright (C) 2006-2008 Jean-Philippe Lang | |||
|
3 | # | |||
|
4 | # This program is free software; you can redistribute it and/or | |||
|
5 | # modify it under the terms of the GNU General Public License | |||
|
6 | # as published by the Free Software Foundation; either version 2 | |||
|
7 | # of the License, or (at your option) any later version. | |||
|
8 | # | |||
|
9 | # This program is distributed in the hope that it will be useful, | |||
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
|
12 | # GNU General Public License for more details. | |||
|
13 | # | |||
|
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 | |||
|
16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
|
17 | ||||
|
18 | require File.dirname(__FILE__) + '/../test_helper' | |||
|
19 | require 'watchers_controller' | |||
|
20 | ||||
|
21 | # Re-raise errors caught by the controller. | |||
|
22 | class WatchersController; def rescue_action(e) raise e end; end | |||
|
23 | ||||
|
24 | class WatchersControllerTest < Test::Unit::TestCase | |||
|
25 | fixtures :projects, :users, :roles, :members, :enabled_modules, | |||
|
26 | :issues, :trackers, :projects_trackers, :issue_statuses, :enumerations, :watchers | |||
|
27 | ||||
|
28 | def setup | |||
|
29 | @controller = WatchersController.new | |||
|
30 | @request = ActionController::TestRequest.new | |||
|
31 | @response = ActionController::TestResponse.new | |||
|
32 | User.current = nil | |||
|
33 | end | |||
|
34 | ||||
|
35 | def test_get_watch_should_be_invalid | |||
|
36 | @request.session[:user_id] = 3 | |||
|
37 | get :watch, :object_type => 'issue', :object_id => '1' | |||
|
38 | assert_response 405 | |||
|
39 | end | |||
|
40 | ||||
|
41 | def test_watch | |||
|
42 | @request.session[:user_id] = 3 | |||
|
43 | assert_difference('Watcher.count') do | |||
|
44 | xhr :post, :watch, :object_type => 'issue', :object_id => '1' | |||
|
45 | assert_response :success | |||
|
46 | assert_select_rjs :replace_html, 'watcher' | |||
|
47 | end | |||
|
48 | assert Issue.find(1).watched_by?(User.find(3)) | |||
|
49 | end | |||
|
50 | ||||
|
51 | def test_unwatch | |||
|
52 | @request.session[:user_id] = 3 | |||
|
53 | assert_difference('Watcher.count', -1) do | |||
|
54 | xhr :post, :unwatch, :object_type => 'issue', :object_id => '2' | |||
|
55 | assert_response :success | |||
|
56 | assert_select_rjs :replace_html, 'watcher' | |||
|
57 | end | |||
|
58 | assert !Issue.find(1).watched_by?(User.find(3)) | |||
|
59 | end | |||
|
60 | ||||
|
61 | def test_new_watcher | |||
|
62 | @request.session[:user_id] = 2 | |||
|
63 | assert_difference('Watcher.count') do | |||
|
64 | xhr :post, :new, :object_type => 'issue', :object_id => '2', :watcher => {:user_id => '4'} | |||
|
65 | assert_response :success | |||
|
66 | assert_select_rjs :replace_html, 'watchers' | |||
|
67 | end | |||
|
68 | assert Issue.find(2).watched_by?(User.find(4)) | |||
|
69 | end | |||
|
70 | end |
@@ -17,30 +17,38 | |||||
17 |
|
17 | |||
18 | class WatchersController < ApplicationController |
|
18 | class WatchersController < ApplicationController | |
19 | layout 'base' |
|
19 | layout 'base' | |
20 | before_filter :require_login, :find_project, :check_project_privacy |
|
20 | before_filter :find_project | |
|
21 | before_filter :require_login, :check_project_privacy, :only => [:watch, :unwatch] | |||
|
22 | before_filter :authorize, :only => :new | |||
21 |
|
23 | |||
22 | def add |
|
24 | verify :method => :post, | |
23 | user = User.current |
|
25 | :only => [ :watch, :unwatch ], | |
24 | @watched.add_watcher(user) |
|
26 | :render => { :nothing => true, :status => :method_not_allowed } | |
25 | respond_to do |format| |
|
27 | ||
26 | format.html { redirect_to :back } |
|
28 | def watch | |
27 | format.js { render(:update) {|page| page.replace_html 'watcher', watcher_link(@watched, user)} } |
|
29 | set_watcher(User.current, true) | |
28 |
|
|
30 | end | |
29 | rescue RedirectBackError |
|
31 | ||
30 | render :text => 'Watcher added.', :layout => true |
|
32 | def unwatch | |
|
33 | set_watcher(User.current, false) | |||
31 | end |
|
34 | end | |
32 |
|
35 | |||
33 |
def |
|
36 | def new | |
34 | user = User.current |
|
37 | @watcher = Watcher.new(params[:watcher]) | |
35 | @watched.remove_watcher(user) |
|
38 | @watcher.watchable = @watched | |
|
39 | @watcher.save if request.post? | |||
36 | respond_to do |format| |
|
40 | respond_to do |format| | |
37 | format.html { redirect_to :back } |
|
41 | format.html { redirect_to :back } | |
38 | format.js { render(:update) {|page| page.replace_html 'watcher', watcher_link(@watched, user)} } |
|
42 | format.js do | |
|
43 | render :update do |page| | |||
|
44 | page.replace_html 'watchers', :partial => 'watchers/watchers', :locals => {:watched => @watched} | |||
|
45 | end | |||
|
46 | end | |||
39 | end |
|
47 | end | |
40 | rescue RedirectBackError |
|
48 | rescue ::ActionController::RedirectBackError | |
41 |
render :text => 'Watcher |
|
49 | render :text => 'Watcher added.', :layout => true | |
42 | end |
|
50 | end | |
43 |
|
51 | |||
44 | private |
|
52 | private | |
45 | def find_project |
|
53 | def find_project | |
46 | klass = Object.const_get(params[:object_type].camelcase) |
|
54 | klass = Object.const_get(params[:object_type].camelcase) | |
@@ -50,4 +58,14 private | |||||
50 | rescue |
|
58 | rescue | |
51 | render_404 |
|
59 | render_404 | |
52 | end |
|
60 | end | |
|
61 | ||||
|
62 | def set_watcher(user, watching) | |||
|
63 | @watched.set_watcher(user, watching) | |||
|
64 | respond_to do |format| | |||
|
65 | format.html { redirect_to :back } | |||
|
66 | format.js { render(:update) {|page| page.replace_html 'watcher', watcher_link(@watched, user)} } | |||
|
67 | end | |||
|
68 | rescue ::ActionController::RedirectBackError | |||
|
69 | render :text => (watching ? 'Watcher added.' : 'Watcher removed.'), :layout => true | |||
|
70 | end | |||
53 | end |
|
71 | end |
@@ -24,7 +24,7 module WatchersHelper | |||||
24 | return '' unless user && user.logged? && object.respond_to?('watched_by?') |
|
24 | return '' unless user && user.logged? && object.respond_to?('watched_by?') | |
25 | watched = object.watched_by?(user) |
|
25 | watched = object.watched_by?(user) | |
26 | url = {:controller => 'watchers', |
|
26 | url = {:controller => 'watchers', | |
27 |
:action => (watched ? ' |
|
27 | :action => (watched ? 'unwatch' : 'watch'), | |
28 | :object_type => object.class.to_s.underscore, |
|
28 | :object_type => object.class.to_s.underscore, | |
29 | :object_id => object.id} |
|
29 | :object_id => object.id} | |
30 | link_to_remote((watched ? l(:button_unwatch) : l(:button_watch)), |
|
30 | link_to_remote((watched ? l(:button_unwatch) : l(:button_watch)), | |
@@ -33,4 +33,9 module WatchersHelper | |||||
33 | :class => (watched ? 'icon icon-fav' : 'icon icon-fav-off')) |
|
33 | :class => (watched ? 'icon icon-fav' : 'icon icon-fav-off')) | |
34 |
|
34 | |||
35 | end |
|
35 | end | |
|
36 | ||||
|
37 | # Returns a comma separated list of users watching the given object | |||
|
38 | def watchers_list(object) | |||
|
39 | object.watcher_users.collect {|u| content_tag('span', link_to_user(u), :class => 'user') }.join(",\n") | |||
|
40 | end | |||
36 | end |
|
41 | end |
@@ -19,5 +19,12 class Watcher < ActiveRecord::Base | |||||
19 | belongs_to :watchable, :polymorphic => true |
|
19 | belongs_to :watchable, :polymorphic => true | |
20 | belongs_to :user |
|
20 | belongs_to :user | |
21 |
|
21 | |||
|
22 | validates_presence_of :user | |||
22 | validates_uniqueness_of :user_id, :scope => [:watchable_type, :watchable_id] |
|
23 | validates_uniqueness_of :user_id, :scope => [:watchable_type, :watchable_id] | |
|
24 | ||||
|
25 | protected | |||
|
26 | ||||
|
27 | def validate | |||
|
28 | errors.add :user_id, :activerecord_error_invalid unless user.nil? || user.active? | |||
|
29 | end | |||
23 | end |
|
30 | end |
@@ -78,6 +78,14 end %> | |||||
78 | </div> |
|
78 | </div> | |
79 | <% end %> |
|
79 | <% end %> | |
80 |
|
80 | |||
|
81 | <% if User.current.allowed_to?(:add_issue_watchers, @project) || | |||
|
82 | (@issue.watchers.any? && User.current.allowed_to?(:view_issue_watchers, @project)) %> | |||
|
83 | <hr /> | |||
|
84 | <div id="watchers"> | |||
|
85 | <%= render :partial => 'watchers/watchers', :locals => {:watched => @issue} %> | |||
|
86 | </div> | |||
|
87 | <% end %> | |||
|
88 | ||||
81 | </div> |
|
89 | </div> | |
82 |
|
90 | |||
83 | <% if @issue.changesets.any? && User.current.allowed_to?(:view_changesets, @project) %> |
|
91 | <% if @issue.changesets.any? && User.current.allowed_to?(:view_changesets, @project) %> |
@@ -633,3 +633,4 setting_mail_handler_api_enabled: Enable WS for incoming emails | |||||
633 | setting_mail_handler_api_key: API key |
|
633 | setting_mail_handler_api_key: API key | |
634 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." |
|
634 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." | |
635 | field_parent_title: Parent page |
|
635 | field_parent_title: Parent page | |
|
636 | label_issue_watchers: Watchers |
@@ -638,3 +638,4 setting_mail_handler_api_enabled: Enable WS for incoming emails | |||||
638 | setting_mail_handler_api_key: API key |
|
638 | setting_mail_handler_api_key: API key | |
639 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." |
|
639 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." | |
640 | field_parent_title: Parent page |
|
640 | field_parent_title: Parent page | |
|
641 | label_issue_watchers: Watchers |
@@ -635,3 +635,4 setting_mail_handler_api_enabled: Enable WS for incoming emails | |||||
635 | setting_mail_handler_api_key: API key |
|
635 | setting_mail_handler_api_key: API key | |
636 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." |
|
636 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." | |
637 | field_parent_title: Parent page |
|
637 | field_parent_title: Parent page | |
|
638 | label_issue_watchers: Watchers |
@@ -634,3 +634,4 setting_mail_handler_api_enabled: Enable WS for incoming emails | |||||
634 | setting_mail_handler_api_key: API key |
|
634 | setting_mail_handler_api_key: API key | |
635 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." |
|
635 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." | |
636 | field_parent_title: Parent page |
|
636 | field_parent_title: Parent page | |
|
637 | label_issue_watchers: Watchers |
@@ -521,6 +521,7 label_reverse_chronological_order: In reverse chronological order | |||||
521 | label_planning: Planning |
|
521 | label_planning: Planning | |
522 | label_incoming_emails: Incoming emails |
|
522 | label_incoming_emails: Incoming emails | |
523 | label_generate_key: Generate a key |
|
523 | label_generate_key: Generate a key | |
|
524 | label_issue_watchers: Watchers | |||
524 |
|
525 | |||
525 | button_login: Login |
|
526 | button_login: Login | |
526 | button_submit: Submit |
|
527 | button_submit: Submit |
@@ -636,3 +636,4 setting_mail_handler_api_enabled: Enable WS for incoming emails | |||||
636 | setting_mail_handler_api_key: API key |
|
636 | setting_mail_handler_api_key: API key | |
637 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." |
|
637 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." | |
638 | field_parent_title: Parent page |
|
638 | field_parent_title: Parent page | |
|
639 | label_issue_watchers: Watchers |
@@ -633,3 +633,4 setting_mail_handler_api_enabled: Enable WS for incoming emails | |||||
633 | setting_mail_handler_api_key: API key |
|
633 | setting_mail_handler_api_key: API key | |
634 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." |
|
634 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." | |
635 | field_parent_title: Parent page |
|
635 | field_parent_title: Parent page | |
|
636 | label_issue_watchers: Watchers |
@@ -521,6 +521,7 label_reverse_chronological_order: Dans l'ordre chronologique inverse | |||||
521 | label_planning: Planning |
|
521 | label_planning: Planning | |
522 | label_incoming_emails: Emails entrants |
|
522 | label_incoming_emails: Emails entrants | |
523 | label_generate_key: Générer une clé |
|
523 | label_generate_key: Générer une clé | |
|
524 | label_issue_watchers: Utilisateurs surveillant cette demande | |||
524 |
|
525 | |||
525 | button_login: Connexion |
|
526 | button_login: Connexion | |
526 | button_submit: Soumettre |
|
527 | button_submit: Soumettre |
@@ -633,3 +633,4 setting_mail_handler_api_enabled: Enable WS for incoming emails | |||||
633 | setting_mail_handler_api_key: API key |
|
633 | setting_mail_handler_api_key: API key | |
634 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." |
|
634 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." | |
635 | field_parent_title: Parent page |
|
635 | field_parent_title: Parent page | |
|
636 | label_issue_watchers: Watchers |
@@ -634,3 +634,4 setting_mail_handler_api_enabled: Web Service engedélyezése a beérkezett leve | |||||
634 | setting_mail_handler_api_key: API kulcs |
|
634 | setting_mail_handler_api_key: API kulcs | |
635 | text_email_delivery_not_configured: "Az E-mail küldés nincs konfigurálva, és az értesítések ki vannak kapcsolva.\nÁllítsd be az SMTP szervert a config/email.yml fájlban és indítsd újra az alkalmazást, hogy érvénybe lépjen." |
|
635 | text_email_delivery_not_configured: "Az E-mail küldés nincs konfigurálva, és az értesítések ki vannak kapcsolva.\nÁllítsd be az SMTP szervert a config/email.yml fájlban és indítsd újra az alkalmazást, hogy érvénybe lépjen." | |
636 | field_parent_title: Parent page |
|
636 | field_parent_title: Parent page | |
|
637 | label_issue_watchers: Watchers |
@@ -633,3 +633,4 setting_mail_handler_api_enabled: Abilita WS per le e-mail in arrivo | |||||
633 | setting_mail_handler_api_key: chiave API |
|
633 | setting_mail_handler_api_key: chiave API | |
634 | text_email_delivery_not_configured: "La consegna via e-mail non è configurata e le notifiche sono disabilitate.\nConfigura il tuo server SMTP in config/email.yml e riavvia l'applicazione per abilitarle." |
|
634 | text_email_delivery_not_configured: "La consegna via e-mail non è configurata e le notifiche sono disabilitate.\nConfigura il tuo server SMTP in config/email.yml e riavvia l'applicazione per abilitarle." | |
635 | field_parent_title: Parent page |
|
635 | field_parent_title: Parent page | |
|
636 | label_issue_watchers: Watchers |
@@ -634,3 +634,4 setting_mail_handler_api_enabled: Enable WS for incoming emails | |||||
634 | setting_mail_handler_api_key: API key |
|
634 | setting_mail_handler_api_key: API key | |
635 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." |
|
635 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." | |
636 | field_parent_title: Parent page |
|
636 | field_parent_title: Parent page | |
|
637 | label_issue_watchers: Watchers |
@@ -633,3 +633,4 setting_mail_handler_api_enabled: Enable WS for incoming emails | |||||
633 | setting_mail_handler_api_key: API key |
|
633 | setting_mail_handler_api_key: API key | |
634 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." |
|
634 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." | |
635 | field_parent_title: Parent page |
|
635 | field_parent_title: Parent page | |
|
636 | label_issue_watchers: Watchers |
@@ -636,3 +636,4 setting_mail_handler_api_key: API raktas | |||||
636 |
|
636 | |||
637 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." |
|
637 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." | |
638 | field_parent_title: Parent page |
|
638 | field_parent_title: Parent page | |
|
639 | label_issue_watchers: Watchers |
@@ -634,3 +634,4 setting_mail_handler_api_enabled: Enable WS for incoming emails | |||||
634 | setting_mail_handler_api_key: API key |
|
634 | setting_mail_handler_api_key: API key | |
635 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." |
|
635 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." | |
636 | field_parent_title: Parent page |
|
636 | field_parent_title: Parent page | |
|
637 | label_issue_watchers: Watchers |
@@ -634,3 +634,4 setting_mail_handler_api_enabled: Enable WS for incoming emails | |||||
634 | setting_mail_handler_api_key: API key |
|
634 | setting_mail_handler_api_key: API key | |
635 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." |
|
635 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." | |
636 | field_parent_title: Parent page |
|
636 | field_parent_title: Parent page | |
|
637 | label_issue_watchers: Watchers |
@@ -633,3 +633,4 setting_mail_handler_api_enabled: Enable WS for incoming emails | |||||
633 | setting_mail_handler_api_key: API key |
|
633 | setting_mail_handler_api_key: API key | |
634 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." |
|
634 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." | |
635 | field_parent_title: Parent page |
|
635 | field_parent_title: Parent page | |
|
636 | label_issue_watchers: Watchers |
@@ -633,3 +633,4 setting_mail_handler_api_enabled: Enable WS for incoming emails | |||||
633 | setting_mail_handler_api_key: API key |
|
633 | setting_mail_handler_api_key: API key | |
634 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." |
|
634 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." | |
635 | field_parent_title: Parent page |
|
635 | field_parent_title: Parent page | |
|
636 | label_issue_watchers: Watchers |
@@ -633,3 +633,4 setting_mail_handler_api_enabled: Enable WS for incoming emails | |||||
633 | setting_mail_handler_api_key: API key |
|
633 | setting_mail_handler_api_key: API key | |
634 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." |
|
634 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." | |
635 | field_parent_title: Parent page |
|
635 | field_parent_title: Parent page | |
|
636 | label_issue_watchers: Watchers |
@@ -633,3 +633,4 setting_mail_handler_api_enabled: Enable WS for incoming emails | |||||
633 | setting_mail_handler_api_key: API key |
|
633 | setting_mail_handler_api_key: API key | |
634 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." |
|
634 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." | |
635 | field_parent_title: Parent page |
|
635 | field_parent_title: Parent page | |
|
636 | label_issue_watchers: Watchers |
@@ -637,3 +637,4 setting_mail_handler_api_enabled: Включить веб-сервис для в | |||||
637 | setting_mail_handler_api_key: API ключ |
|
637 | setting_mail_handler_api_key: API ключ | |
638 | text_email_delivery_not_configured: "Параметры работы с почтовым сервером не настроены и функция уведомления по email не активна.\nНастроить параметры для вашего SMTP сервера вы можете в файле config/email.yml. Для применения изменений перезапустите приложение." |
|
638 | text_email_delivery_not_configured: "Параметры работы с почтовым сервером не настроены и функция уведомления по email не активна.\nНастроить параметры для вашего SMTP сервера вы можете в файле config/email.yml. Для применения изменений перезапустите приложение." | |
639 | field_parent_title: Parent page |
|
639 | field_parent_title: Parent page | |
|
640 | label_issue_watchers: Watchers |
@@ -634,3 +634,4 setting_mail_handler_api_enabled: Enable WS for incoming emails | |||||
634 | setting_mail_handler_api_key: API key |
|
634 | setting_mail_handler_api_key: API key | |
635 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." |
|
635 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." | |
636 | field_parent_title: Parent page |
|
636 | field_parent_title: Parent page | |
|
637 | label_issue_watchers: Watchers |
@@ -634,3 +634,4 setting_mail_handler_api_enabled: Enable WS for incoming emails | |||||
634 | setting_mail_handler_api_key: API key |
|
634 | setting_mail_handler_api_key: API key | |
635 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." |
|
635 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." | |
636 | field_parent_title: Parent page |
|
636 | field_parent_title: Parent page | |
|
637 | label_issue_watchers: Watchers |
@@ -636,3 +636,4 setting_mail_handler_api_enabled: Enable WS for incoming emails | |||||
636 | setting_mail_handler_api_key: API key |
|
636 | setting_mail_handler_api_key: API key | |
637 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." |
|
637 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." | |
638 | field_parent_title: Parent page |
|
638 | field_parent_title: Parent page | |
|
639 | label_issue_watchers: Watchers |
@@ -635,3 +635,4 setting_mail_handler_api_enabled: Enable WS for incoming emails | |||||
635 | setting_mail_handler_api_key: API key |
|
635 | setting_mail_handler_api_key: API key | |
636 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." |
|
636 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." | |
637 | field_parent_title: Parent page |
|
637 | field_parent_title: Parent page | |
|
638 | label_issue_watchers: Watchers |
@@ -634,3 +634,4 enumeration_issue_priorities: 項目優先權 | |||||
634 | enumeration_doc_categories: 文件分類 |
|
634 | enumeration_doc_categories: 文件分類 | |
635 | enumeration_activities: 活動 (時間追蹤) |
|
635 | enumeration_activities: 活動 (時間追蹤) | |
636 | field_parent_title: Parent page |
|
636 | field_parent_title: Parent page | |
|
637 | label_issue_watchers: Watchers |
@@ -634,3 +634,4 enumeration_doc_categories: 文档类别 | |||||
634 | enumeration_activities: 活动(时间跟踪) |
|
634 | enumeration_activities: 活动(时间跟踪) | |
635 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." |
|
635 | text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." | |
636 | field_parent_title: Parent page |
|
636 | field_parent_title: Parent page | |
|
637 | label_issue_watchers: Watchers |
@@ -46,6 +46,9 Redmine::AccessControl.map do |map| | |||||
46 | # Gantt & calendar |
|
46 | # Gantt & calendar | |
47 | map.permission :view_gantt, :projects => :gantt |
|
47 | map.permission :view_gantt, :projects => :gantt | |
48 | map.permission :view_calendar, :projects => :calendar |
|
48 | map.permission :view_calendar, :projects => :calendar | |
|
49 | # Watchers | |||
|
50 | map.permission :view_issue_watchers, {} | |||
|
51 | map.permission :add_issue_watchers, {:watchers => :new} | |||
49 | end |
|
52 | end | |
50 |
|
53 | |||
51 | map.project_module :time_tracking do |map| |
|
54 | map.project_module :time_tracking do |map| |
@@ -15,6 +15,8 roles_001: | |||||
15 | - :add_issue_notes |
|
15 | - :add_issue_notes | |
16 | - :move_issues |
|
16 | - :move_issues | |
17 | - :delete_issues |
|
17 | - :delete_issues | |
|
18 | - :view_issue_watchers | |||
|
19 | - :add_issue_watchers | |||
18 | - :manage_public_queries |
|
20 | - :manage_public_queries | |
19 | - :save_queries |
|
21 | - :save_queries | |
20 | - :view_gantt |
|
22 | - :view_gantt | |
@@ -58,6 +60,7 roles_002: | |||||
58 | - :add_issue_notes |
|
60 | - :add_issue_notes | |
59 | - :move_issues |
|
61 | - :move_issues | |
60 | - :delete_issues |
|
62 | - :delete_issues | |
|
63 | - :view_issue_watchers | |||
61 | - :save_queries |
|
64 | - :save_queries | |
62 | - :view_gantt |
|
65 | - :view_gantt | |
63 | - :view_calendar |
|
66 | - :view_calendar | |
@@ -95,6 +98,7 roles_003: | |||||
95 | - :manage_issue_relations |
|
98 | - :manage_issue_relations | |
96 | - :add_issue_notes |
|
99 | - :add_issue_notes | |
97 | - :move_issues |
|
100 | - :move_issues | |
|
101 | - :view_issue_watchers | |||
98 | - :save_queries |
|
102 | - :save_queries | |
99 | - :view_gantt |
|
103 | - :view_gantt | |
100 | - :view_calendar |
|
104 | - :view_calendar |
@@ -13,6 +13,7 module Redmine | |||||
13 |
|
13 | |||
14 | class_eval do |
|
14 | class_eval do | |
15 | has_many :watchers, :as => :watchable, :dependent => :delete_all |
|
15 | has_many :watchers, :as => :watchable, :dependent => :delete_all | |
|
16 | has_many :watcher_users, :through => :watchers, :source => :user | |||
16 | end |
|
17 | end | |
17 | end |
|
18 | end | |
18 | end |
|
19 | end | |
@@ -22,25 +23,40 module Redmine | |||||
22 | base.extend ClassMethods |
|
23 | base.extend ClassMethods | |
23 | end |
|
24 | end | |
24 |
|
25 | |||
|
26 | # Returns an array of users that are proposed as watchers | |||
|
27 | def addable_watcher_users | |||
|
28 | self.project.users.sort - self.watcher_users | |||
|
29 | end | |||
|
30 | ||||
|
31 | # Adds user as a watcher | |||
25 | def add_watcher(user) |
|
32 | def add_watcher(user) | |
26 | self.watchers << Watcher.new(:user => user) |
|
33 | self.watchers << Watcher.new(:user => user) | |
27 | end |
|
34 | end | |
28 |
|
35 | |||
|
36 | # Removes user from the watchers list | |||
29 | def remove_watcher(user) |
|
37 | def remove_watcher(user) | |
30 | return nil unless user && user.is_a?(User) |
|
38 | return nil unless user && user.is_a?(User) | |
31 | Watcher.delete_all "watchable_type = '#{self.class}' AND watchable_id = #{self.id} AND user_id = #{user.id}" |
|
39 | Watcher.delete_all "watchable_type = '#{self.class}' AND watchable_id = #{self.id} AND user_id = #{user.id}" | |
32 | end |
|
40 | end | |
33 |
|
41 | |||
|
42 | # Adds/removes watcher | |||
|
43 | def set_watcher(user, watching=true) | |||
|
44 | watching ? add_watcher(user) : remove_watcher(user) | |||
|
45 | end | |||
|
46 | ||||
|
47 | # Returns if object is watched by user | |||
34 | def watched_by?(user) |
|
48 | def watched_by?(user) | |
35 | !self.watchers.find(:first, |
|
49 | !self.watchers.find(:first, | |
36 | :conditions => ["#{Watcher.table_name}.user_id = ?", user.id]).nil? |
|
50 | :conditions => ["#{Watcher.table_name}.user_id = ?", user.id]).nil? | |
37 | end |
|
51 | end | |
38 |
|
52 | |||
|
53 | # Returns an array of watchers' email addresses | |||
39 | def watcher_recipients |
|
54 | def watcher_recipients | |
40 | self.watchers.collect { |w| w.user.mail if w.user.active? }.compact |
|
55 | self.watchers.collect { |w| w.user.mail if w.user.active? }.compact | |
41 | end |
|
56 | end | |
42 |
|
57 | |||
43 | module ClassMethods |
|
58 | module ClassMethods | |
|
59 | # Returns the objects that are watched by user | |||
44 | def watched_by(user) |
|
60 | def watched_by(user) | |
45 | find(:all, |
|
61 | find(:all, | |
46 | :include => :watchers, |
|
62 | :include => :watchers, | |
@@ -50,4 +66,4 module Redmine | |||||
50 | end |
|
66 | end | |
51 | end |
|
67 | end | |
52 | end |
|
68 | end | |
53 |
end |
|
69 | end |
@@ -138,8 +138,8 module ActionView #:nodoc: | |||||
138 | def add_options(option_tags, options, value = nil) |
|
138 | def add_options(option_tags, options, value = nil) | |
139 | option_tags = "<option value=\"\"></option>\n" + option_tags if options[:include_blank] |
|
139 | option_tags = "<option value=\"\"></option>\n" + option_tags if options[:include_blank] | |
140 |
|
140 | |||
141 |
if |
|
141 | if options[:prompt] | |
142 | ("<option value=\"\">#{options[:prompt].kind_of?(String) ? options[:prompt] : l(:actionview_instancetag_blank_option)}</option>\n") + option_tags |
|
142 | ("<option value=\"\">--- #{options[:prompt].kind_of?(String) ? options[:prompt] : l(:actionview_instancetag_blank_option)} ---</option>\n") + option_tags | |
143 | else |
|
143 | else | |
144 | option_tags |
|
144 | option_tags | |
145 | end |
|
145 | end |
General Comments 0
You need to be logged in to leave comments.
Login now