Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/concerns/issuable.rb')
-rw-r--r--app/models/concerns/issuable.rb44
1 files changed, 39 insertions, 5 deletions
diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb
index b81a9b51e1c..f8389865f91 100644
--- a/app/models/concerns/issuable.rb
+++ b/app/models/concerns/issuable.rb
@@ -33,6 +33,7 @@ module Issuable
DESCRIPTION_LENGTH_MAX = 1.megabyte
DESCRIPTION_HTML_LENGTH_MAX = 5.megabytes
SEARCHABLE_FIELDS = %w(title description).freeze
+ MAX_NUMBER_OF_ASSIGNEES_OR_REVIEWERS = 200
STATE_ID_MAP = {
opened: 1,
@@ -95,6 +96,7 @@ module Issuable
# to avoid breaking the existing Issuables which may have their descriptions longer
validates :description, length: { maximum: DESCRIPTION_LENGTH_MAX }, allow_blank: true, on: :create
validate :description_max_length_for_new_records_is_valid, on: :update
+ validate :validate_assignee_size_length, unless: :importing?
before_validation :truncate_description_on_import!
@@ -166,6 +168,11 @@ module Issuable
def locking_enabled?
false
end
+
+ def max_number_of_assignees_or_reviewers_message
+ # Assignees will be included in https://gitlab.com/gitlab-org/gitlab/-/issues/368936
+ format(_("total must be less than or equal to %{size}"), size: MAX_NUMBER_OF_ASSIGNEES_OR_REVIEWERS)
+ end
end
# We want to use optimistic lock for cases when only title or description are involved
@@ -227,11 +234,19 @@ module Issuable
def truncate_description_on_import!
self.description = description&.slice(0, Issuable::DESCRIPTION_LENGTH_MAX) if importing?
end
+
+ def validate_assignee_size_length
+ return true unless Feature.enabled?(:limit_assignees_per_issuable)
+ return true unless assignees.size > MAX_NUMBER_OF_ASSIGNEES_OR_REVIEWERS
+
+ errors.add :assignees,
+ -> (_object, _data) { self.class.max_number_of_assignees_or_reviewers_message }
+ end
end
class_methods do
def participant_includes
- [:assignees, :author, { notes: [:author, :award_emoji] }]
+ [:author, :award_emoji, { notes: [:author, :award_emoji, :system_note_metadata] }]
end
# Searches for records with a matching title.
@@ -383,10 +398,12 @@ module Issuable
milestone_table = Milestone.arel_table
grouping_columns << milestone_table[:id]
grouping_columns << milestone_table[:due_date]
- elsif %w(merged_at_desc merged_at_asc).include?(sort)
+ elsif %w(merged_at_desc merged_at_asc merged_at).include?(sort)
+ grouping_columns << MergeRequest::Metrics.arel_table[:id]
grouping_columns << MergeRequest::Metrics.arel_table[:merged_at]
- elsif %w(closed_at_desc closed_at_asc).include?(sort)
- grouping_columns << MergeRequest::Metrics.arel_table[:closed_at]
+ elsif %w(closed_at_desc closed_at_asc closed_at).include?(sort)
+ grouping_columns << MergeRequest::Metrics.arel_table[:id]
+ grouping_columns << MergeRequest::Metrics.arel_table[:latest_closed_at]
end
grouping_columns
@@ -431,7 +448,16 @@ module Issuable
end
def assignee_or_author?(user)
- author_id == user.id || assignees.exists?(user.id)
+ author_id == user.id || assignee?(user)
+ end
+
+ def assignee?(user)
+ # Necessary so we can preload the association and avoid N + 1 queries
+ if assignees.loaded?
+ assignees.to_a.include?(user)
+ else
+ assignees.exists?(user.id)
+ end
end
def today?
@@ -630,6 +656,14 @@ module Issuable
def draftless_title_changed(old_title)
old_title != title
end
+
+ def read_ability_for(participable_source)
+ return super if participable_source == self
+
+ name = participable_source.try(:issuable_ability_name) || :read_issuable_participables
+
+ { name: name, subject: self }
+ end
end
Issuable.prepend_mod_with('Issuable')