diff options
Diffstat (limited to 'app/models/draft_note.rb')
-rw-r--r-- | app/models/draft_note.rb | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/app/models/draft_note.rb b/app/models/draft_note.rb new file mode 100644 index 00000000000..febede9beba --- /dev/null +++ b/app/models/draft_note.rb @@ -0,0 +1,122 @@ +# frozen_string_literal: true +class DraftNote < ApplicationRecord + include DiffPositionableNote + include Gitlab::Utils::StrongMemoize + include Sortable + include ShaAttribute + + PUBLISH_ATTRS = %i(noteable_id noteable_type type note).freeze + DIFF_ATTRS = %i(position original_position change_position commit_id).freeze + + sha_attribute :commit_id + + # Attribute used to store quick actions changes and users referenced. + attr_accessor :commands_changes + attr_accessor :users_referenced + + # Text with quick actions filtered out + attr_accessor :rendered_note + + attr_accessor :review + + belongs_to :author, class_name: 'User' + belongs_to :merge_request + + validates :merge_request_id, presence: true + validates :author_id, presence: true, uniqueness: { scope: [:merge_request_id, :discussion_id] }, if: :discussion_id? + validates :discussion_id, allow_nil: true, format: { with: /\A\h{40}\z/ } + + scope :authored_by, ->(u) { where(author_id: u.id) } + + delegate :file_path, :file_hash, :file_identifier_hash, to: :diff_file, allow_nil: true + + def self.positions + where.not(position: nil) + .select(:position) + .map(&:position) + end + + def project + merge_request.target_project + end + + # noteable_id and noteable_type methods + # are used to generate discussion_id on Discussion.discussion_id + def noteable_id + merge_request_id + end + + def noteable + merge_request + end + + def noteable_type + "MergeRequest" + end + + def for_commit? + commit_id.present? + end + + def importing? + false + end + + def resolvable? + false + end + + def emoji_awardable? + false + end + + def on_diff? + position&.complete? + end + + def type + return 'DiffNote' if on_diff? + return 'DiscussionNote' if discussion_id.present? + + 'Note' + end + + def references + { + users: users_referenced, + commands: commands_changes + } + end + + def line_code + @line_code ||= diff_file&.line_code_for_position(original_position) + end + + def publish_params + attrs = PUBLISH_ATTRS.dup + attrs.concat(DIFF_ATTRS) if on_diff? + params = slice(*attrs) + params[:in_reply_to_discussion_id] = discussion_id if discussion_id.present? + params[:review_id] = review.id if review.present? + + params + end + + def self.preload_author(draft_notes) + ActiveRecord::Associations::Preloader.new.preload(draft_notes, { author: :status }) + end + + def diff_file + strong_memoize(:diff_file) do + file = original_position&.diff_file(project.repository) + + file&.unfold_diff_lines(original_position) + + file + end + end + + def commit + @commit ||= project.commit(commit_id) if commit_id.present? + end +end |