]> source.dussan.org Git - redmine.git/commitdiff
Mark edited journal notes as "Edited" (#31505).
authorGo MAEDA <maeda@farend.jp>
Sun, 17 Jul 2022 04:40:01 +0000 (04:40 +0000)
committerGo MAEDA <maeda@farend.jp>
Sun, 17 Jul 2022 04:40:01 +0000 (04:40 +0000)
Patch by Marius BALTEANU.

git-svn-id: https://svn.redmine.org/redmine/trunk@21713 e93f8b46-1217-0410-a6f0-8f06a7374b81

app/controllers/journals_controller.rb
app/helpers/journals_helper.rb
app/models/journal.rb
app/views/issues/tabs/_history.html.erb
app/views/journals/update.js.erb
config/locales/en.yml
db/migrate/20220714093000_add_journal_updated_on.rb [new file with mode: 0644]
db/migrate/20220714093010_add_journal_updated_by.rb [new file with mode: 0644]
public/stylesheets/application.css
test/fixtures/journals.yml
test/functional/issues_controller_test.rb

index a9cf41d8c4b99834d955ccd0ef441d433d402406..40c679e5e186ab32a756abb45b49ef7242234ebd 100644 (file)
@@ -91,7 +91,9 @@ class JournalsController < ApplicationController
 
   def update
     (render_403; return false) unless @journal.editable_by?(User.current)
-    @journal.safe_attributes = params[:journal]
+    journal_attributes = params[:journal]
+    journal_attributes[:updated_by] = User.current
+    @journal.safe_attributes = journal_attributes
     @journal.save
     @journal.destroy if @journal.details.empty? && @journal.notes.blank?
     call_hook(:controller_journals_edit_post, {:journal => @journal, :params => params})
index dd759ff8857e4d5d882e95ad393fed6371ddf9f3..18224c196b22f4312535ed5d63f929aaf6f21762 100644 (file)
@@ -79,4 +79,10 @@ module JournalsHelper
     css_classes = journal.private_notes? ? 'badge badge-private private' : ''
     content_tag('span', content.html_safe, :id => "journal-#{journal.id}-private_notes", :class => css_classes)
   end
+
+  def render_journal_update_info(journal)
+    return if journal.created_on == journal.updated_on
+
+    content_tag('span', "· #{l(:label_edited)}", :title => l(:label_time_by_author, :time => format_time(journal.updated_on), :author => journal.updated_by), :class => 'update-info')
+  end
 end
index 01d5debcd796d45e5d761f707c15d99c662b1bf4..919a07dd2e9b2d629f5a5a0775472b926e84e91f 100644 (file)
@@ -26,6 +26,7 @@ class Journal < ActiveRecord::Base
   belongs_to :issue, :foreign_key => :journalized_id
 
   belongs_to :user
+  belongs_to :updated_by, :class_name => 'User'
   has_many :details, :class_name => "JournalDetail", :dependent => :delete_all, :inverse_of => :journal
   attr_accessor :indice
 
@@ -78,6 +79,7 @@ class Journal < ActiveRecord::Base
   safe_attributes(
     'private_notes',
     :if => lambda {|journal, user| user.allowed_to?(:set_notes_private, journal.project)})
+  safe_attributes 'updated_by'
 
   # Returns a SQL condition to filter out journals with notes that are not visible to user
   def self.visible_notes_condition(user=User.current, options={})
index 4b908acb560ef814d6b2ec1106dfa15c83f2abd3..8c6f6d31be78f4f1c97bf545111de2825844ecb1 100644 (file)
@@ -15,6 +15,7 @@
       <%= avatar(journal.user) %>
       <%= authoring journal.created_on, journal.user, :label => :label_updated_time_by %>
       <%= render_private_notes_indicator(journal) %>
+      <%= render_journal_update_info(journal) %>
     </h4>
 
     <% if journal.details.any? %>
index 3d6be8d940156d4c8d93b146048e84e22faf4f15..87320c5d4a0b28de0818b8a4aa6dc3d15ce8e869 100644 (file)
@@ -7,6 +7,13 @@
   $("#journal-<%= @journal.id %>-notes").replaceWith('<%= escape_javascript(render_notes(@journal.issue, @journal, :reply_links => authorize_for('issues', 'edit'))) %>');
   $("#journal-<%= @journal.id %>-notes").show();
   $("#journal-<%= @journal.id %>-form").remove();
+  var journal_header = $("#change-<%= @journal.id %> h4");
+  var journal_updated_info = journal_header.find("span.update-info");
+  if (journal_updated_info.length > 0) {
+    journal_updated_info.replaceWith('<%= escape_javascript(render_journal_update_info(@journal)) %>');
+  } else {
+    journal_header.append('<%= escape_javascript(render_journal_update_info(@journal)) %>');
+  }
   setupWikiTableSortableHeader();
 <% end %>
 
index bfaf7f80419e40479fb6a8c4bedc14c6f22f18ff..74067d42cce4ef951ee60a66d9ddd78948200dbc 100644 (file)
@@ -1129,6 +1129,8 @@ en:
   label_my_bookmarks: My bookmarks
   label_assign_to_me: Assign to me
   label_default_query: Default query
+  label_edited: Edited
+  label_time_by_author: "%{time} by %{author}"
 
   button_login: Login
   button_submit: Submit
diff --git a/db/migrate/20220714093000_add_journal_updated_on.rb b/db/migrate/20220714093000_add_journal_updated_on.rb
new file mode 100644 (file)
index 0000000..bf2c1b0
--- /dev/null
@@ -0,0 +1,10 @@
+class AddJournalUpdatedOn < ActiveRecord::Migration[5.2]
+  def up
+    add_column :journals, :updated_on, :datetime, :after => :created_on
+    Journal.update_all('updated_on = created_on')
+  end
+
+  def down
+    remove_column :journals, :updated_on
+  end
+end
diff --git a/db/migrate/20220714093010_add_journal_updated_by.rb b/db/migrate/20220714093010_add_journal_updated_by.rb
new file mode 100644 (file)
index 0000000..02bf65e
--- /dev/null
@@ -0,0 +1,9 @@
+class AddJournalUpdatedBy < ActiveRecord::Migration[5.2]
+  def up
+    add_column :journals, :updated_by_id, :integer, :default => nil, :after => :updated_on
+  end
+
+  def down
+    remove_column :journals, :updated_by_id
+  end
+end
index 6d7402f66119649073009468c5cd92ff7abdfafb..8f676fc806616c00833167e47dde751d49e07e04 100644 (file)
@@ -610,6 +610,7 @@ div.journal ul.details a, ul.revision-info a {color:#70A7CD;}
 div.journal ul.details a:hover, ul.revision-info a:hover {color:#D14848;}
 body.avatars-on div.journal {padding-left:32px;}
 div.journal h4 img.gravatar {margin-left:-32px;}
+div.journal span.update-info {color: #666; font-size: 0.9em;}
 
 #history .tab-content {
   padding: 0 6px;
index bc7bc91b9af291561c20087c8dd855f275f050c7..e6cbd95cfaa9d6ba7bbd84fde29b6f49fdf70d35 100644 (file)
@@ -1,13 +1,16 @@
 ---
 journals_001:
   created_on: <%= 2.days.ago.to_date.to_s(:db) %>
+  updated_on: <%= 1.days.ago.to_date.to_s(:db) %>
   notes: "Journal notes"
   id: 1
   journalized_type: Issue
   user_id: 1
   journalized_id: 1
+  updated_by_id: 1
 journals_002:
   created_on: <%= 1.days.ago.to_date.to_s(:db) %>
+  updated_on: <%= 1.days.ago.to_date.to_s(:db) %>
   notes: "Some notes with Redmine links: #2, r2."
   id: 2
   journalized_type: Issue
@@ -15,6 +18,7 @@ journals_002:
   journalized_id: 1
 journals_003:
   created_on: <%= 1.days.ago.to_date.to_s(:db) %>
+  updated_on: <%= 1.days.ago.to_date.to_s(:db) %>
   notes: "A comment with inline image: !picture.jpg! and a reference to #1 and r2."
   id: 3
   journalized_type: Issue
@@ -22,6 +26,7 @@ journals_003:
   journalized_id: 2
 journals_004:
   created_on: <%= 1.days.ago.to_date.to_s(:db) %>
+  updated_on: <%= 1.days.ago.to_date.to_s(:db) %>
   notes: "A comment with a private version."
   id: 4
   journalized_type: Issue
@@ -30,6 +35,7 @@ journals_004:
 journals_005:
   id: 5
   created_on: <%= 1.days.ago.to_date.to_s(:db) %>
+  updated_on: <%= 1.days.ago.to_date.to_s(:db) %>
   notes: "A comment on a private issue."
   user_id: 2
   journalized_type: Issue
index 60d1ff638283114e8ac788a4fc8f2b210835bd40..71dcfd6ad6ef8c6033dc61651a7e2120a107c5e0 100644 (file)
@@ -2894,6 +2894,16 @@ class IssuesControllerTest < Redmine::ControllerTest
     assert_select "#change-#{not_visible.id}", 0
   end
 
+  def test_show_should_mark_notes_as_edited_only_for_edited_notes
+    get :show, :params => {:id => 1}
+    assert_response :success
+
+    journal = Journal.find(1)
+    journal_title = l(:label_time_by_author, :time => format_time(journal.updated_on), :author => journal.updated_by)
+    assert_select "#change-1 h4 span.update-info[title=?]", journal_title, :text => '· Edited'
+    assert_select "#change-2 h4 span.update-info", 0
+  end
+
   def test_show_atom
     with_settings :text_formatting => 'textile' do
       get(