Feature #1554 » private_messages.patch
app/helpers/journals_helper.rb (working copy) | ||
---|---|---|
39 | 39 |
onclick = "new Ajax.Request('#{url_for(url)}', {asynchronous:true, evalScripts:true, method:'get'}); return false;" |
40 | 40 |
link_to text, '#', options.merge(:onclick => onclick) |
41 | 41 |
end |
42 | ||
43 |
def only_private_messages?(journals) |
|
44 |
journals.each do |journal| |
|
45 |
return false if ! journal.private |
|
46 |
end |
|
47 |
|
|
48 |
true |
|
49 |
end |
|
42 | 50 |
end |
app/models/mailer.rb (working copy) | ||
---|---|---|
58 | 58 |
# Mailer.deliver_issue_edit(journal) => sends an email to issue recipients |
59 | 59 |
def issue_edit(journal) |
60 | 60 |
issue = journal.journalized.reload |
61 |
private = journal[:private] |
|
61 | 62 |
redmine_headers 'Project' => issue.project.identifier, |
62 | 63 |
'Issue-Id' => issue.id, |
63 | 64 |
'Issue-Author' => issue.author.login |
... | ... | |
65 | 66 |
message_id journal |
66 | 67 |
references issue |
67 | 68 |
@author = journal.user |
68 |
recipients issue.recipients |
|
69 | ||
70 |
@recipients ||= [] |
|
71 |
watchers = issue.watcher_recipients - @recipients |
|
72 | ||
73 |
processed_recipients = prepare_receivers issue.recipients, issue.project, private |
|
74 |
processed_watchers = prepare_receivers watchers, issue.project, private |
|
75 | ||
76 |
recipients processed_recipients |
|
69 | 77 |
# Watchers in cc |
70 |
cc(issue.watcher_recipients - @recipients)
|
|
78 |
cc(processed_watchers)
|
|
71 | 79 |
s = "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] " |
72 | 80 |
s << "(#{issue.status.name}) " if journal.new_value_for('status_id') |
73 | 81 |
s << issue.subject |
... | ... | |
448 | 456 |
def mylogger |
449 | 457 |
RAILS_DEFAULT_LOGGER |
450 | 458 |
end |
459 | ||
460 |
# Method for recipients or watchers preparation |
|
461 |
def prepare_receivers(receivers, project, private) |
|
462 |
processed_receivers = Array.new() |
|
463 | ||
464 |
receivers.each do |recepient| |
|
465 |
current_user = User.find_by_mail(recepient) |
|
466 |
can_see_private_messages = current_user.allowed_to?(:view_private_messages, project) |
|
467 | ||
468 |
if private |
|
469 |
next if ! can_see_private_messages |
|
470 |
end |
|
471 | ||
472 |
processed_receivers << recepient |
|
473 |
end |
|
474 | ||
475 |
processed_receivers |
|
476 |
end |
|
477 | ||
451 | 478 |
end |
452 | 479 | |
453 | 480 |
# Patch TMail so that message_id is not overwritten |
app/models/issue.rb (working copy) | ||
---|---|---|
388 | 388 |
end |
389 | 389 |
end |
390 | 390 | |
391 |
def init_journal(user, notes = "") |
|
392 |
@current_journal ||= Journal.new(:journalized => self, :user => user, :notes => notes) |
|
391 |
def init_journal(user, notes = "", private = false)
|
|
392 |
@current_journal ||= Journal.new(:journalized => self, :user => user, :notes => notes, :private => private)
|
|
393 | 393 |
@issue_before_change = self.clone |
394 | 394 |
@issue_before_change.status = self.status |
395 | 395 |
@custom_values_before_change = {} |
app/controllers/issues_controller.rb (working copy) | ||
---|---|---|
286 | 286 |
@time_entry.attributes = params[:time_entry] |
287 | 287 | |
288 | 288 |
@notes = params[:notes] || (params[:issue].present? ? params[:issue][:notes] : nil) |
289 |
@issue.init_journal(User.current, @notes) |
|
289 |
@private_message = params[:private_message] || false |
|
290 |
@issue.init_journal(User.current, @notes, @private_message) |
|
290 | 291 |
@issue.safe_attributes = params[:issue] |
291 | 292 |
end |
292 | 293 |
app/controllers/journals_controller.rb (working copy) | ||
---|---|---|
83 | 83 |
(render_403; return false) unless @journal.editable_by?(User.current) |
84 | 84 |
if request.post? |
85 | 85 |
@journal.update_attributes(:notes => params[:notes]) if params[:notes] |
86 |
@journal.update_attributes(:private => params[:private_message] || false) |
|
86 | 87 |
@journal.destroy if @journal.details.empty? && @journal.notes.blank? |
87 | 88 |
call_hook(:controller_journals_edit_post, { :journal => @journal, :params => params}) |
88 | 89 |
respond_to do |format| |
app/views/journals/_notes_form.rhtml (working copy) | ||
---|---|---|
16 | 16 |
<%= link_to l(:button_cancel), '#', :onclick => "Element.remove('journal-#{@journal.id}-form'); " + |
17 | 17 |
"Element.show('journal-#{@journal.id}-notes'); return false;" %></p> |
18 | 18 | |
19 |
<%= check_box_tag :private_message, true, @journal.private, :id => "private_message_#{@journal.id}" %> |
|
20 |
<%= label_tag "private_message_#{@journal.id}", 'Private message', :style => 'font-weight:bold;' %> |
|
21 |
|
|
19 | 22 |
<div id="journal_<%= @journal.id %>_preview" class="wiki"></div> |
20 | 23 |
<% end %> |
21 | 24 |
<%= wikitoolbar_for "journal_#{@journal.id}_notes" %> |
app/views/issues/_history.rhtml (working copy) | ||
---|---|---|
1 | 1 |
<% reply_links = authorize_for('issues', 'edit') -%> |
2 |
<% view_private = User.current.allowed_to?(:view_private_messages, @project) %> |
|
3 |
<% @skipped = 0 %> |
|
4 | ||
2 | 5 |
<% for journal in journals %> |
3 |
<div id="change-<%= journal.id %>" class="<%= journal.css_classes %>"> |
|
4 |
<h4><div class="journal-link"><%= link_to "##{journal.indice}", :anchor => "note-#{journal.indice}" %></div> |
|
6 | ||
7 |
<% private = journal.private %> |
|
8 | ||
9 |
<% if private %> |
|
10 |
<% if ! view_private %> |
|
11 |
<% @skipped += 1 %> |
|
12 |
<% next %> |
|
13 |
<% end %> |
|
14 |
<% end %> |
|
15 | ||
16 |
<div id="change-<%= journal.id %>" class="<%= journal.css_classes %> <%= 'private' if journal.private %>"> |
|
17 |
<h4><div class="journal-link"><%= link_to "##{journal.indice - @skipped}", :anchor => "note-#{journal.indice - @skipped}" %></div> |
|
5 | 18 |
<%= avatar(journal.user, :size => "24") %> |
6 |
<%= content_tag('a', '', :name => "note-#{journal.indice}")%> |
|
7 |
<%= authoring journal.created_on, journal.user, :label => :label_updated_time_by %></h4> |
|
19 |
<%= content_tag('a', '', :name => "note-#{journal.indice - @skipped}")%> |
|
20 |
<%= authoring journal.created_on, journal.user, :label => :label_updated_time_by %> |
|
21 |
<% if journal.private %> |
|
22 |
<span>(private)</span> |
|
23 |
<% end %> |
|
24 |
</h4> |
|
8 | 25 |
|
9 | 26 |
<% if journal.details.any? %> |
10 | 27 |
<ul class="details"> |
app/views/issues/show.rhtml (working copy) | ||
---|---|---|
90 | 90 |
<% end %> |
91 | 91 | |
92 | 92 |
<% if @journals.present? %> |
93 |
<div id="history"> |
|
94 |
<h3><%=l(:label_history)%></h3> |
|
95 |
<%= render :partial => 'history', :locals => { :issue => @issue, :journals => @journals } %> |
|
96 |
</div> |
|
93 |
<% view_private = User.current.allowed_to?(:view_private_messages, @project) %> |
|
94 |
<% if ! only_private_messages?(@journals) || view_private %> |
|
95 |
<div id="history"> |
|
96 |
<h3><%=l(:label_history)%></h3> |
|
97 |
<%= render :partial => 'history', :locals => { :issue => @issue, :journals => @journals } %> |
|
98 |
</div> |
|
99 |
<% end %> |
|
97 | 100 |
<% end %> |
98 | 101 | |
99 | 102 |
app/views/issues/_edit.rhtml (working copy) | ||
---|---|---|
5 | 5 |
:method => :put, |
6 | 6 |
:multipart => true} do |f| %> |
7 | 7 |
<%= error_messages_for 'issue', 'time_entry' %> |
8 | ||
9 |
<% view_private = User.current.allowed_to?(:view_private_messages, @project) %> |
|
10 | ||
8 | 11 |
<div class="box"> |
9 | 12 |
<% if @edit_allowed || !@allowed_statuses.empty? %> |
10 | 13 |
<fieldset class="tabular"><legend><%= l(:label_change_properties) %> |
... | ... | |
31 | 34 |
<% end %> |
32 | 35 |
</fieldset> |
33 | 36 |
<% end %> |
34 |
|
|
37 | ||
35 | 38 |
<fieldset><legend><%= l(:field_notes) %></legend> |
36 | 39 |
<%= text_area_tag 'notes', @notes, :cols => 60, :rows => 10, :class => 'wiki-edit' %> |
37 | 40 |
<%= wikitoolbar_for 'notes' %> |
38 | 41 |
<%= call_hook(:view_issues_edit_notes_bottom, { :issue => @issue, :notes => @notes, :form => f }) %> |
39 |
|
|
42 | ||
43 |
<% if view_private %> |
|
44 |
<%= check_box_tag :private_message, true, false %> |
|
45 |
<%= label_tag :private_message, 'Private message', :style => 'font-weight:bold;' %> |
|
46 |
<% end %> |
|
47 | ||
40 | 48 |
<p><%=l(:label_attachment_plural)%><br /><%= render :partial => 'attachments/form' %></p> |
41 | 49 |
</fieldset> |
42 | 50 |
</div> |
43 |
|
|
51 | ||
44 | 52 |
<%= f.hidden_field :lock_version %> |
45 | 53 |
<%= submit_tag l(:button_submit) %> |
46 |
<%= link_to_remote l(:label_preview),
|
|
54 |
<%= link_to_remote l(:label_preview), |
|
47 | 55 |
{ :url => preview_issue_path(:project_id => @project, :id => @issue), |
48 | 56 |
:method => 'post', |
49 | 57 |
:update => 'preview', |
... | ... | |
52 | 60 |
}, :accesskey => accesskey(:preview) %> |
53 | 61 |
<% end %> |
54 | 62 | |
55 |
<div id="preview" class="wiki"></div> |
|
63 |
<div id="preview" class="wiki"></div> |
lib/redmine.rb (working copy) | ||
---|---|---|
85 | 85 |
map.permission :view_issue_watchers, {} |
86 | 86 |
map.permission :add_issue_watchers, {:watchers => :new} |
87 | 87 |
map.permission :delete_issue_watchers, {:watchers => :destroy} |
88 |
# Private messages |
|
89 |
map.permission :view_private_messages, {} |
|
88 | 90 |
end |
89 | 91 |
|
90 | 92 |
map.project_module :time_tracking do |map| |