summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/controllers/journals_controller.rb4
-rw-r--r--app/helpers/journals_helper.rb6
-rw-r--r--app/models/journal.rb2
-rw-r--r--app/views/issues/tabs/_history.html.erb1
-rw-r--r--app/views/journals/update.js.erb7
-rw-r--r--config/locales/en.yml2
-rw-r--r--db/migrate/20220714093000_add_journal_updated_on.rb10
-rw-r--r--db/migrate/20220714093010_add_journal_updated_by.rb9
-rw-r--r--public/stylesheets/application.css1
-rw-r--r--test/fixtures/journals.yml6
-rw-r--r--test/functional/issues_controller_test.rb10
11 files changed, 57 insertions, 1 deletions
diff --git a/app/controllers/journals_controller.rb b/app/controllers/journals_controller.rb
index a9cf41d8c..40c679e5e 100644
--- a/app/controllers/journals_controller.rb
+++ b/app/controllers/journals_controller.rb
@@ -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})
diff --git a/app/helpers/journals_helper.rb b/app/helpers/journals_helper.rb
index dd759ff88..18224c196 100644
--- a/app/helpers/journals_helper.rb
+++ b/app/helpers/journals_helper.rb
@@ -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
diff --git a/app/models/journal.rb b/app/models/journal.rb
index 01d5debcd..919a07dd2 100644
--- a/app/models/journal.rb
+++ b/app/models/journal.rb
@@ -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={})
diff --git a/app/views/issues/tabs/_history.html.erb b/app/views/issues/tabs/_history.html.erb
index 4b908acb5..8c6f6d31b 100644
--- a/app/views/issues/tabs/_history.html.erb
+++ b/app/views/issues/tabs/_history.html.erb
@@ -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? %>
diff --git a/app/views/journals/update.js.erb b/app/views/journals/update.js.erb
index 3d6be8d94..87320c5d4 100644
--- a/app/views/journals/update.js.erb
+++ b/app/views/journals/update.js.erb
@@ -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 %>
diff --git a/config/locales/en.yml b/config/locales/en.yml
index bfaf7f804..74067d42c 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -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
index 000000000..bf2c1b0cd
--- /dev/null
+++ b/db/migrate/20220714093000_add_journal_updated_on.rb
@@ -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
index 000000000..02bf65e54
--- /dev/null
+++ b/db/migrate/20220714093010_add_journal_updated_by.rb
@@ -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
diff --git a/public/stylesheets/application.css b/public/stylesheets/application.css
index 6d7402f66..8f676fc80 100644
--- a/public/stylesheets/application.css
+++ b/public/stylesheets/application.css
@@ -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;
diff --git a/test/fixtures/journals.yml b/test/fixtures/journals.yml
index bc7bc91b9..e6cbd95cf 100644
--- a/test/fixtures/journals.yml
+++ b/test/fixtures/journals.yml
@@ -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
diff --git a/test/functional/issues_controller_test.rb b/test/functional/issues_controller_test.rb
index 60d1ff638..71dcfd6ad 100644
--- a/test/functional/issues_controller_test.rb
+++ b/test/functional/issues_controller_test.rb
@@ -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(