Feature #1554 » private_messages-2011-12-14-v1.3.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')
|
| 81 |
s << "[PRIVATE] " if journal.private |
|
| 73 | 82 |
s << issue.subject |
| 74 | 83 |
subject s |
| 75 | 84 |
body :issue => issue, |
| ... | ... | |
| 463 | 472 |
def mylogger |
| 464 | 473 |
Rails.logger |
| 465 | 474 |
end |
| 475 | ||
| 476 |
# Method for recipients or watchers preparation |
|
| 477 |
def prepare_receivers(receivers, project, private) |
|
| 478 |
processed_receivers = Array.new() |
|
| 479 | ||
| 480 |
receivers.each do |recepient| |
|
| 481 |
current_user = User.find_by_mail(recepient) |
|
| 482 |
can_see_private_messages = current_user.allowed_to?(:view_private_messages, project) |
|
| 483 | ||
| 484 |
if private |
|
| 485 |
next if ! can_see_private_messages |
|
| 486 |
end |
|
| 487 | ||
| 488 |
processed_receivers << recepient |
|
| 489 |
end |
|
| 490 | ||
| 491 |
processed_receivers |
|
| 492 |
end |
|
| 493 | ||
| 466 | 494 |
end |
| 467 | 495 | |
| 468 | 496 |
# Patch TMail so that message_id is not overwritten |
| app/models/mail_handler.rb (working copy) | ||
|---|---|---|
| 159 | 159 |
issue.safe_attributes = issue_attributes_from_keywords(issue) |
| 160 | 160 |
issue.safe_attributes = {'custom_field_values' => custom_field_values_from_keywords(issue)}
|
| 161 | 161 |
journal.notes = cleaned_up_text_body |
| 162 |
journal.private = 1 if !email.subject.to_s.index('[PRIVATE]').nil?
|
|
| 162 | 163 |
add_attachments(issue) |
| 163 | 164 |
issue.save! |
| 164 | 165 |
logger.info "MailHandler: issue ##{issue.id} updated by #{user}" if logger && logger.info
|
| app/models/issue.rb (working copy) | ||
|---|---|---|
| 391 | 391 |
end |
| 392 | 392 |
end |
| 393 | 393 | |
| 394 |
def init_journal(user, notes = "") |
|
| 395 |
@current_journal ||= Journal.new(:journalized => self, :user => user, :notes => notes) |
|
| 394 |
def init_journal(user, notes = "", private = false)
|
|
| 395 |
@current_journal ||= Journal.new(:journalized => self, :user => user, :notes => notes, :private => private)
|
|
| 396 | 396 |
@issue_before_change = self.clone |
| 397 | 397 |
@issue_before_change.status = self.status |
| 398 | 398 |
@custom_values_before_change = {}
|
| app/controllers/issues_controller.rb (working copy) | ||
|---|---|---|
| 291 | 291 |
@time_entry.attributes = params[:time_entry] |
| 292 | 292 | |
| 293 | 293 |
@notes = params[:notes] || (params[:issue].present? ? params[:issue][:notes] : nil) |
| 294 |
@issue.init_journal(User.current, @notes) |
|
| 294 |
@private_message = params[:private_message] || false |
|
| 295 |
@issue.init_journal(User.current, @notes, @private_message) |
|
| 295 | 296 |
@issue.safe_attributes = params[:issue] |
| 296 | 297 |
end |
| 297 | 298 | |
| 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/controllers/activities_controller.rb (working copy) | ||
|---|---|---|
| 40 | 40 | |
| 41 | 41 |
events = @activity.events(@date_from, @date_to) |
| 42 | 42 | |
| 43 |
events.delete_if { |e| e.is_a?(Journal) && e.private && !User.current.allowed_to?(:view_private_messages, @project) }
|
|
| 44 | ||
| 43 | 45 |
if events.empty? || stale?(:etag => [@activity.scope, @date_to, @date_from, @with_subprojects, @author, events.first, User.current, current_language]) |
| 44 | 46 |
respond_to do |format| |
| 45 | 47 |
format.html {
|
| app/views/journals/_notes_form.html.erb (working copy) | ||
|---|---|---|
| 17 | 17 |
<%= link_to l(:button_cancel), '#', :onclick => "Element.remove('journal-#{@journal.id}-form'); " +
|
| 18 | 18 |
"Element.show('journal-#{@journal.id}-notes'); return false;" %></p>
|
| 19 | 19 | |
| 20 |
<%= check_box_tag :private_message, true, @journal.private, :id => "private_message_#{@journal.id}" %>
|
|
| 21 |
<%= label_tag "private_message_#{@journal.id}", 'Private message', :style => 'font-weight:bold;' %>
|
|
| 22 |
|
|
| 20 | 23 |
<div id="journal_<%= @journal.id %>_preview" class="wiki"></div> |
| 21 | 24 |
<% end %> |
| 22 | 25 |
<%= wikitoolbar_for "journal_#{@journal.id}_notes" %>
|
| app/views/issues/show.html.erb (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.html.erb (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) %> |
| ... | ... | |
| 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> |
| ... | ... | |
| 52 | 60 |
}, :accesskey => accesskey(:preview) %> |
| 53 | 61 |
<% end %> |
| 54 | 62 | |
| 55 |
<div id="preview" class="wiki"></div> |
|
| 63 |
<div id="preview" class="wiki"></div> |
|
| app/views/issues/_history.html.erb (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"> |
| 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| |