diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index b9d375d9b64..0ff6ab48808 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -181,15 +181,15 @@ module ApplicationHelper end def edited_time_ago_with_tooltip(object, placement: 'top', html_class: 'time_ago', include_author: false) - return if object.updated_at == object.created_at + return if object.last_edited_at == object.created_at || object.last_edited_at.blank? - content_tag :small, class: "edited-text" do - output = content_tag(:span, "Edited ") - output << time_ago_with_tooltip(object.updated_at, placement: placement, html_class: html_class) + content_tag :small, class: 'edited-text' do + output = content_tag(:span, 'Edited ') + output << time_ago_with_tooltip(object.last_edited_at, placement: placement, html_class: html_class) - if include_author && object.updated_by - output << content_tag(:span, " by ") - output << link_to_member(object.project, object.updated_by, avatar: false, author_class: nil) + if include_author && object.last_edited_by + output << content_tag(:span, ' by ') + output << link_to_member(object.project, object.last_edited_by, avatar: false, author_class: nil) end output diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb index 26dbf4d9570..de1ad840daa 100644 --- a/app/models/concerns/issuable.rb +++ b/app/models/concerns/issuable.rb @@ -28,6 +28,7 @@ module Issuable belongs_to :author, class_name: "User" belongs_to :assignee, class_name: "User" belongs_to :updated_by, class_name: "User" + belongs_to :last_edited_by, class_name: 'User' belongs_to :milestone has_many :notes, as: :noteable, inverse_of: :noteable, dependent: :destroy do def authors_loaded? diff --git a/app/models/note.rb b/app/models/note.rb index b06985b4a6f..943211ca991 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -38,6 +38,7 @@ class Note < ActiveRecord::Base belongs_to :noteable, polymorphic: true, touch: true belongs_to :author, class_name: "User" belongs_to :updated_by, class_name: "User" + belongs_to :last_edited_by, class_name: 'User' has_many :todos, dependent: :destroy has_many :events, as: :target, dependent: :destroy diff --git a/app/services/issuable_base_service.rb b/app/services/issuable_base_service.rb index 7072d78b28d..889e4508758 100644 --- a/app/services/issuable_base_service.rb +++ b/app/services/issuable_base_service.rb @@ -218,6 +218,13 @@ class IssuableBaseService < BaseService if issuable.changed? || params.present? issuable.assign_attributes(params.merge(updated_by: current_user)) + if has_title_or_description_changed?(issuable) + issuable.assign_attributes(params.merge( + last_edited_at: Time.now, + last_edited_by: current_user + )) + end + before_update(issuable) if issuable.with_transaction_returning_status { issuable.save } @@ -240,6 +247,10 @@ class IssuableBaseService < BaseService old_label_ids.sort != new_label_ids.sort end + def has_title_or_description_changed?(issuable) + issuable.title_changed? || issuable.description_changed? + end + def change_state(issuable) case params.delete(:state_event) when 'reopen' diff --git a/app/services/notes/update_service.rb b/app/services/notes/update_service.rb index 75fd08ea0a9..4b4f383abf2 100644 --- a/app/services/notes/update_service.rb +++ b/app/services/notes/update_service.rb @@ -5,7 +5,11 @@ module Notes old_mentioned_users = note.mentioned_users.to_a + note.assign_attributes(params) + params.merge!(last_edited_at: Time.now, last_edited_by: current_user) if note.note_changed? + note.update_attributes(params.merge(updated_by: current_user)) + note.create_new_cross_references!(current_user) if note.previous_changes.include?('note') diff --git a/db/migrate/20170503021915_add_last_edited_at_and_last_edited_by_id_to_issues.rb b/db/migrate/20170503021915_add_last_edited_at_and_last_edited_by_id_to_issues.rb new file mode 100644 index 00000000000..6ac10723c82 --- /dev/null +++ b/db/migrate/20170503021915_add_last_edited_at_and_last_edited_by_id_to_issues.rb @@ -0,0 +1,14 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class AddLastEditedAtAndLastEditedByIdToIssues < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + # Set this constant to true if this migration requires downtime. + DOWNTIME = false + + def change + add_column :issues, :last_edited_at, :timestamp + add_column :issues, :last_edited_by_id, :integer + end +end diff --git a/db/migrate/20170503022512_add_last_edited_at_and_last_edited_by_id_to_notes.rb b/db/migrate/20170503022512_add_last_edited_at_and_last_edited_by_id_to_notes.rb new file mode 100644 index 00000000000..a44a1feab16 --- /dev/null +++ b/db/migrate/20170503022512_add_last_edited_at_and_last_edited_by_id_to_notes.rb @@ -0,0 +1,14 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class AddLastEditedAtAndLastEditedByIdToNotes < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + # Set this constant to true if this migration requires downtime. + DOWNTIME = false + + def change + add_column :notes, :last_edited_at, :timestamp + add_column :notes, :last_edited_by_id, :integer + end +end diff --git a/db/migrate/20170503022548_add_last_edited_at_and_last_edited_by_id_to_merge_requests.rb b/db/migrate/20170503022548_add_last_edited_at_and_last_edited_by_id_to_merge_requests.rb new file mode 100644 index 00000000000..7a1acdcbf69 --- /dev/null +++ b/db/migrate/20170503022548_add_last_edited_at_and_last_edited_by_id_to_merge_requests.rb @@ -0,0 +1,14 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class AddLastEditedAtAndLastEditedByIdToMergeRequests < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + # Set this constant to true if this migration requires downtime. + DOWNTIME = false + + def change + add_column :merge_requests, :last_edited_at, :timestamp + add_column :merge_requests, :last_edited_by_id, :integer + end +end diff --git a/db/schema.rb b/db/schema.rb index be6684f3a6b..b173b467abf 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170426181740) do +ActiveRecord::Schema.define(version: 20170503022548) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -488,6 +488,8 @@ ActiveRecord::Schema.define(version: 20170426181740) do t.integer "relative_position" t.datetime "closed_at" t.integer "cached_markdown_version" + t.datetime "last_edited_at" + t.integer "last_edited_by_id" end add_index "issues", ["assignee_id"], name: "index_issues_on_assignee_id", using: :btree @@ -674,6 +676,8 @@ ActiveRecord::Schema.define(version: 20170426181740) do t.text "description_html" t.integer "time_estimate" t.integer "cached_markdown_version" + t.datetime "last_edited_at" + t.integer "last_edited_by_id" end add_index "merge_requests", ["assignee_id"], name: "index_merge_requests_on_assignee_id", using: :btree @@ -774,6 +778,8 @@ ActiveRecord::Schema.define(version: 20170426181740) do t.string "discussion_id" t.text "note_html" t.integer "cached_markdown_version" + t.datetime "last_edited_at" + t.integer "last_edited_by_id" end add_index "notes", ["author_id"], name: "index_notes_on_author_id", using: :btree