@@ -1,33 +1,33 | |||||
1 | <div id="issue_descr_fields" <%= 'style="display:none"' unless @issue.new_record? || @issue.errors.any? %>> |
|
1 | <div id="issue_descr_fields" <%= 'style="display:none"' unless @issue.new_record? || @issue.errors.any? %>> | |
2 | <p><%= f.select :tracker_id, @project.trackers.collect {|t| [t.name, t.id]}, :required => true %></p> |
|
2 | <p><%= f.select :tracker_id, @project.trackers.collect {|t| [t.name, t.id]}, :required => true %></p> | |
3 | <%= observe_field :issue_tracker_id, :url => { :action => :update_form, :project_id => @project, :id => @issue }, |
|
3 | <%= observe_field :issue_tracker_id, :url => { :action => :update_form, :project_id => @project, :id => @issue }, | |
4 | :update => :attributes, |
|
4 | :update => :attributes, | |
5 | :with => "Form.serialize('issue-form')" %> |
|
5 | :with => "Form.serialize('issue-form')" %> | |
6 |
|
6 | |||
7 | <p><%= f.text_field :subject, :size => 80, :required => true %></p> |
|
7 | <p><%= f.text_field :subject, :size => 80, :required => true %></p> | |
8 | <p><%= f.text_area :description, |
|
8 | <p><%= f.text_area :description, | |
9 | :cols => 60, |
|
9 | :cols => 60, | |
10 | :rows => (@issue.description.blank? ? 10 : [[10, @issue.description.length / 50].max, 100].min), |
|
10 | :rows => (@issue.description.blank? ? 10 : [[10, @issue.description.length / 50].max, 100].min), | |
11 | :accesskey => accesskey(:edit), |
|
11 | :accesskey => accesskey(:edit), | |
12 | :class => 'wiki-edit' %></p> |
|
12 | :class => 'wiki-edit' %></p> | |
13 | </div> |
|
13 | </div> | |
14 |
|
14 | |||
15 | <div id="attributes" class="attributes"> |
|
15 | <div id="attributes" class="attributes"> | |
16 | <%= render :partial => 'attributes' %> |
|
16 | <%= render :partial => 'attributes' %> | |
17 | </div> |
|
17 | </div> | |
18 |
|
18 | |||
19 | <% if @issue.new_record? %> |
|
19 | <% if @issue.new_record? %> | |
20 | <p><label><%=l(:label_attachment_plural)%></label><%= render :partial => 'attachments/form' %></p> |
|
20 | <p><label><%=l(:label_attachment_plural)%></label><%= render :partial => 'attachments/form' %></p> | |
21 | <% end %> |
|
21 | <% end %> | |
22 |
|
22 | |||
23 | <% if @issue.new_record? && User.current.allowed_to?(:add_issue_watchers, @project) -%> |
|
23 | <% if @issue.new_record? && User.current.allowed_to?(:add_issue_watchers, @project) -%> | |
24 | <p><label><%= l(:label_issue_watchers) %></label> |
|
24 | <p><label><%= l(:label_issue_watchers) %></label> | |
25 | <% @issue.project.users.sort.each do |user| -%> |
|
25 | <% @issue.project.users.sort.each do |user| -%> | |
26 |
<label class="floating"><%= check_box_tag 'issue[watcher_user_ids][]', user.id, @issue.watche |
|
26 | <label class="floating"><%= check_box_tag 'issue[watcher_user_ids][]', user.id, @issue.watched_by?(user) %> <%=h user %></label> | |
27 | <% end -%> |
|
27 | <% end -%> | |
28 | </p> |
|
28 | </p> | |
29 | <% end %> |
|
29 | <% end %> | |
30 |
|
30 | |||
31 | <%= call_hook(:view_issues_form_details_bottom, { :issue => @issue, :form => f }) %> |
|
31 | <%= call_hook(:view_issues_form_details_bottom, { :issue => @issue, :form => f }) %> | |
32 |
|
32 | |||
33 | <%= wikitoolbar_for 'issue_description' %> |
|
33 | <%= wikitoolbar_for 'issue_description' %> |
@@ -1,71 +1,70 | |||||
1 | # ActsAsWatchable |
|
1 | # ActsAsWatchable | |
2 | module Redmine |
|
2 | module Redmine | |
3 | module Acts |
|
3 | module Acts | |
4 | module Watchable |
|
4 | module Watchable | |
5 | def self.included(base) |
|
5 | def self.included(base) | |
6 | base.extend ClassMethods |
|
6 | base.extend ClassMethods | |
7 | end |
|
7 | end | |
8 |
|
8 | |||
9 | module ClassMethods |
|
9 | module ClassMethods | |
10 | def acts_as_watchable(options = {}) |
|
10 | def acts_as_watchable(options = {}) | |
11 | return if self.included_modules.include?(Redmine::Acts::Watchable::InstanceMethods) |
|
11 | return if self.included_modules.include?(Redmine::Acts::Watchable::InstanceMethods) | |
12 | send :include, Redmine::Acts::Watchable::InstanceMethods |
|
12 | send :include, Redmine::Acts::Watchable::InstanceMethods | |
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 | has_many :watcher_users, :through => :watchers, :source => :user | |
17 |
|
17 | |||
18 | attr_protected :watcher_ids, :watcher_user_ids |
|
18 | attr_protected :watcher_ids, :watcher_user_ids | |
19 | end |
|
19 | end | |
20 | end |
|
20 | end | |
21 | end |
|
21 | end | |
22 |
|
22 | |||
23 | module InstanceMethods |
|
23 | module InstanceMethods | |
24 | def self.included(base) |
|
24 | def self.included(base) | |
25 | base.extend ClassMethods |
|
25 | base.extend ClassMethods | |
26 | end |
|
26 | end | |
27 |
|
27 | |||
28 | # Returns an array of users that are proposed as watchers |
|
28 | # Returns an array of users that are proposed as watchers | |
29 | def addable_watcher_users |
|
29 | def addable_watcher_users | |
30 | self.project.users.sort - self.watcher_users |
|
30 | self.project.users.sort - self.watcher_users | |
31 | end |
|
31 | end | |
32 |
|
32 | |||
33 | # Adds user as a watcher |
|
33 | # Adds user as a watcher | |
34 | def add_watcher(user) |
|
34 | def add_watcher(user) | |
35 | self.watchers << Watcher.new(:user => user) |
|
35 | self.watchers << Watcher.new(:user => user) | |
36 | end |
|
36 | end | |
37 |
|
37 | |||
38 | # Removes user from the watchers list |
|
38 | # Removes user from the watchers list | |
39 | def remove_watcher(user) |
|
39 | def remove_watcher(user) | |
40 | return nil unless user && user.is_a?(User) |
|
40 | return nil unless user && user.is_a?(User) | |
41 | Watcher.delete_all "watchable_type = '#{self.class}' AND watchable_id = #{self.id} AND user_id = #{user.id}" |
|
41 | Watcher.delete_all "watchable_type = '#{self.class}' AND watchable_id = #{self.id} AND user_id = #{user.id}" | |
42 | end |
|
42 | end | |
43 |
|
43 | |||
44 | # Adds/removes watcher |
|
44 | # Adds/removes watcher | |
45 | def set_watcher(user, watching=true) |
|
45 | def set_watcher(user, watching=true) | |
46 | watching ? add_watcher(user) : remove_watcher(user) |
|
46 | watching ? add_watcher(user) : remove_watcher(user) | |
47 | end |
|
47 | end | |
48 |
|
48 | |||
49 | # Returns if object is watched by user |
|
49 | # Returns true if object is watched by user | |
50 | def watched_by?(user) |
|
50 | def watched_by?(user) | |
51 | !self.watchers.find(:first, |
|
51 | !!(user && self.watchers.detect {|w| w.user_id == user.id }) | |
52 | :conditions => ["#{Watcher.table_name}.user_id = ?", user.id]).nil? |
|
|||
53 | end |
|
52 | end | |
54 |
|
53 | |||
55 | # Returns an array of watchers' email addresses |
|
54 | # Returns an array of watchers' email addresses | |
56 | def watcher_recipients |
|
55 | def watcher_recipients | |
57 | self.watchers.collect { |w| w.user.mail if w.user.active? }.compact |
|
56 | self.watchers.collect { |w| w.user.mail if w.user.active? }.compact | |
58 | end |
|
57 | end | |
59 |
|
58 | |||
60 | module ClassMethods |
|
59 | module ClassMethods | |
61 | # Returns the objects that are watched by user |
|
60 | # Returns the objects that are watched by user | |
62 | def watched_by(user) |
|
61 | def watched_by(user) | |
63 | find(:all, |
|
62 | find(:all, | |
64 | :include => :watchers, |
|
63 | :include => :watchers, | |
65 | :conditions => ["#{Watcher.table_name}.user_id = ?", user.id]) |
|
64 | :conditions => ["#{Watcher.table_name}.user_id = ?", user.id]) | |
66 | end |
|
65 | end | |
67 | end |
|
66 | end | |
68 | end |
|
67 | end | |
69 | end |
|
68 | end | |
70 | end |
|
69 | end | |
71 | end |
|
70 | end |
General Comments 0
You need to be logged in to leave comments.
Login now