Patch #44274 » example-journalized-news.patch
| app/controllers/news_controller.rb | ||
|---|---|---|
| 31 | 31 | |
| 32 | 32 |
helper :watchers |
| 33 | 33 |
helper :attachments |
| 34 |
helper :issues |
|
| 35 |
helper :custom_fields |
|
| 34 | 36 | |
| 35 | 37 |
def index |
| 36 | 38 |
case params[:format] |
| ... | ... | |
| 68 | 70 |
end |
| 69 | 71 | |
| 70 | 72 |
def show |
| 73 |
@journals = @news.journals.visible.preload(:user, :details).reorder(:id).to_a |
|
| 71 | 74 |
@comments = @news.comments.preload(:commented).to_a |
| 72 | 75 |
@comments.reverse! if User.current.wants_comments_in_reverse_order? |
| 73 | 76 | |
| ... | ... | |
| 105 | 108 |
end |
| 106 | 109 | |
| 107 | 110 |
def update |
| 111 |
@news.init_journal(User.current) |
|
| 108 | 112 |
@news.safe_attributes = params[:news] |
| 109 | 113 |
@news.save_attachments(params[:attachments] || (params[:news] && params[:news][:uploads])) |
| 110 | 114 |
if @news.save |
| app/models/news.rb | ||
|---|---|---|
| 30 | 30 |
validates_length_of :summary, :maximum => 255 |
| 31 | 31 | |
| 32 | 32 |
acts_as_attachable :edit_permission => :manage_news, |
| 33 |
:delete_permission => :manage_news |
|
| 33 |
:delete_permission => :manage_news, |
|
| 34 |
:after_add => :attachment_added, |
|
| 35 |
:after_remove => :attachment_removed |
|
| 34 | 36 |
acts_as_searchable :columns => ['title', 'summary', "#{table_name}.description"],
|
| 35 | 37 |
:preload => :project |
| 36 | 38 |
acts_as_event :url => Proc.new {|o| {:controller => 'news', :action => 'show', :id => o.id}}
|
| ... | ... | |
| 38 | 40 |
:author_key => :author_id |
| 39 | 41 |
acts_as_watchable |
| 40 | 42 |
acts_as_webhookable |
| 43 |
acts_as_journalized :activity_type => 'news', |
|
| 44 |
:attributes => %w(title summary description), |
|
| 45 |
:permissions => {
|
|
| 46 |
:edit_notes => :manage_news, |
|
| 47 |
:add_watchers => :manage_news |
|
| 48 |
} |
|
| 41 | 49 |
include News::Webhookable |
| 42 | 50 | |
| 43 | 51 |
after_create :add_author_as_watcher |
| 44 | 52 |
after_create_commit :send_notification |
| 53 |
after_save :create_journal |
|
| 45 | 54 | |
| 46 | 55 |
scope :visible, (lambda do |*args| |
| 47 | 56 |
joins(:project). |
| ... | ... | |
| 54 | 63 |
!user.nil? && user.allowed_to?(:view_news, project) |
| 55 | 64 |
end |
| 56 | 65 | |
| 66 |
def init_journal(user, notes = '') |
|
| 67 |
@current_journal ||= Journal.new(:journalized => self, :user => user, :notes => notes) |
|
| 68 |
end |
|
| 69 | ||
| 70 |
attr_reader :current_journal |
|
| 71 | ||
| 72 |
# Callback on file attachment |
|
| 73 |
def attachment_added(attachment) |
|
| 74 |
if current_journal && !attachment.new_record? |
|
| 75 |
current_journal.journalize_attachment(attachment, :added) |
|
| 76 |
end |
|
| 77 |
end |
|
| 78 | ||
| 79 |
# Callback on attachment deletion |
|
| 80 |
def attachment_removed(attachment) |
|
| 81 |
if current_journal && !attachment.new_record? |
|
| 82 |
current_journal.journalize_attachment(attachment, :removed) |
|
| 83 |
current_journal.save |
|
| 84 |
end |
|
| 85 |
end |
|
| 86 | ||
| 87 |
def journal_event_title(journal) |
|
| 88 |
"#{l(:label_news)}: #{title}"
|
|
| 89 |
end |
|
| 90 | ||
| 91 |
def journal_event_type(journal) |
|
| 92 |
'news' |
|
| 93 |
end |
|
| 94 | ||
| 57 | 95 |
# Returns true if the news can be commented by user |
| 58 | 96 |
def commentable?(user=User.current) |
| 59 | 97 |
user.allowed_to?(:comment_news, project) |
| ... | ... | |
| 91 | 129 | |
| 92 | 130 |
private |
| 93 | 131 | |
| 132 |
def create_journal |
|
| 133 |
current_journal&.save |
|
| 134 |
@current_journal = nil |
|
| 135 |
end |
|
| 136 | ||
| 94 | 137 |
def add_author_as_watcher |
| 95 | 138 |
Watcher.create(:watchable => self, :user => author) |
| 96 | 139 |
end |
| app/views/news/show.html.erb | ||
|---|---|---|
| 35 | 35 |
</div> |
| 36 | 36 |
<br /> |
| 37 | 37 | |
| 38 |
<% if @journals.any? %> |
|
| 39 |
<div id="history" class="journals"> |
|
| 40 |
<h3><%= l(:label_history) %></h3> |
|
| 41 |
<% @journals.each do |journal| %> |
|
| 42 |
<div id="change-<%= journal.id %>" class="<%= journal.css_classes %>"> |
|
| 43 |
<h4 class="journal-header"> |
|
| 44 |
<span class="journal-info"><%= avatar(journal.user) %> <%= authoring journal.created_on, journal.user, :label => :label_updated_time_by %></span> |
|
| 45 |
</h4> |
|
| 46 |
<ul class="details"> |
|
| 47 |
<% journal.visible_details.each do |detail| %> |
|
| 48 |
<% if detail.property == 'attr' && detail.prop_key == 'description' %> |
|
| 49 |
<%# The diff of JournalsController is specific to issues, show it inline %> |
|
| 50 |
<li> |
|
| 51 |
<%= l(:text_journal_changed_no_detail, :label => content_tag(:strong, l(:field_description))).html_safe %> |
|
| 52 |
<details> |
|
| 53 |
<summary><%= l(:label_diff) %></summary> |
|
| 54 |
<pre class="text-diff"><%= Redmine::Helpers::Diff.new(detail.value, detail.old_value).to_html %></pre> |
|
| 55 |
</details> |
|
| 56 |
</li> |
|
| 57 |
<% else %> |
|
| 58 |
<% details_to_strings([detail]).each do |string| %> |
|
| 59 |
<li><%= string %></li> |
|
| 60 |
<% end %> |
|
| 61 |
<% end %> |
|
| 62 |
<% end %> |
|
| 63 |
</ul> |
|
| 64 |
<%= textilizable(journal, :notes) if journal.notes.present? %> |
|
| 65 |
</div> |
|
| 66 |
<% end %> |
|
| 67 |
</div> |
|
| 68 |
<% end %> |
|
| 69 | ||
| 38 | 70 |
<div id="comments" class="journals"> |
| 39 | 71 |
<h3 class="comments"><%= l(:label_comment_plural) %></h3> |
| 40 | 72 |
<% if @news.commentable? && @comments.size >= 3 %> |
| lib/redmine/preparation.rb | ||
|---|---|---|
| 27 | 27 | |
| 28 | 28 |
# Journalized types, registered before their classes are loaded |
| 29 | 29 |
Redmine::Acts::Journalized.register 'Issue' |
| 30 |
Redmine::Acts::Journalized.register 'News' |
|
| 30 | 31 | |
| 31 | 32 |
Scm::Base.add "Subversion" |
| 32 | 33 |
Scm::Base.add "Mercurial" |
| ... | ... | |
| 409 | 410 |
Activity.map do |activity| |
| 410 | 411 |
activity.register :issues, :class_name => %w(Issue Journal) |
| 411 | 412 |
activity.register :changesets |
| 412 |
activity.register :news |
|
| 413 |
activity.register :news, :class_name => %w(News Journal)
|
|
| 413 | 414 |
activity.register :documents, :class_name => %w(Document Attachment) |
| 414 | 415 |
activity.register :files, :class_name => 'Attachment' |
| 415 | 416 |
activity.register :wiki_edits, :class_name => 'WikiContentVersion', :default => false |