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/services/projects/open_issues_count_service.rb')
-rw-r--r--app/services/projects/open_issues_count_service.rb98
1 files changed, 68 insertions, 30 deletions
diff --git a/app/services/projects/open_issues_count_service.rb b/app/services/projects/open_issues_count_service.rb
index dc450311db2..8b7a418edf5 100644
--- a/app/services/projects/open_issues_count_service.rb
+++ b/app/services/projects/open_issues_count_service.rb
@@ -7,8 +7,12 @@ module Projects
include Gitlab::Utils::StrongMemoize
# Cache keys used to store issues count
- PUBLIC_COUNT_KEY = 'public_open_issues_count'
- TOTAL_COUNT_KEY = 'total_open_issues_count'
+ # TOTAL_COUNT_KEY includes confidential and hidden issues (admin)
+ # TOTAL_COUNT_WITHOUT_HIDDEN_KEY includes confidential issues but not hidden issues (reporter and above)
+ # PUBLIC_COUNT_WITHOUT_HIDDEN_KEY does not include confidential or hidden issues (guest)
+ TOTAL_COUNT_KEY = 'project_open_issues_including_hidden_count'
+ TOTAL_COUNT_WITHOUT_HIDDEN_KEY = 'project_open_issues_without_hidden_count'
+ PUBLIC_COUNT_WITHOUT_HIDDEN_KEY = 'project_open_public_issues_without_hidden_count'
def initialize(project, user = nil)
@user = user
@@ -16,16 +20,53 @@ module Projects
super(project)
end
+ # rubocop: disable CodeReuse/ActiveRecord
+ def refresh_cache(&block)
+ if block_given?
+ super(&block)
+ else
+ update_cache_for_key(total_count_cache_key) do
+ issues_with_hidden
+ end
+
+ update_cache_for_key(public_count_without_hidden_cache_key) do
+ issues_without_hidden_without_confidential
+ end
+
+ update_cache_for_key(total_count_without_hidden_cache_key) do
+ issues_without_hidden_with_confidential
+ end
+ end
+ end
+
+ private
+
+ def relation_for_count
+ self.class.query(@project, public_only: public_only?, include_hidden: include_hidden?)
+ end
+
def cache_key_name
- public_only? ? PUBLIC_COUNT_KEY : TOTAL_COUNT_KEY
+ if include_hidden?
+ TOTAL_COUNT_KEY
+ elsif public_only?
+ PUBLIC_COUNT_WITHOUT_HIDDEN_KEY
+ else
+ TOTAL_COUNT_WITHOUT_HIDDEN_KEY
+ end
+ end
+
+ def include_hidden?
+ user_is_admin?
end
def public_only?
!user_is_at_least_reporter?
end
- def relation_for_count
- self.class.query(@project, public_only: public_only?)
+ def user_is_admin?
+ strong_memoize(:user_is_admin) do
+ @user&.can_admin_all_resources?
+ end
end
def user_is_at_least_reporter?
@@ -34,46 +75,43 @@ module Projects
end
end
- def public_count_cache_key
- cache_key(PUBLIC_COUNT_KEY)
+ def total_count_without_hidden_cache_key
+ cache_key(TOTAL_COUNT_WITHOUT_HIDDEN_KEY)
+ end
+
+ def public_count_without_hidden_cache_key
+ cache_key(PUBLIC_COUNT_WITHOUT_HIDDEN_KEY)
end
def total_count_cache_key
cache_key(TOTAL_COUNT_KEY)
end
- # rubocop: disable CodeReuse/ActiveRecord
- def refresh_cache(&block)
- if block_given?
- super(&block)
- else
- count_grouped_by_confidential = self.class.query(@project, public_only: false).group(:confidential).count
- public_count = count_grouped_by_confidential[false] || 0
- total_count = public_count + (count_grouped_by_confidential[true] || 0)
+ def issues_with_hidden
+ self.class.query(@project, public_only: false, include_hidden: true).count
+ end
- update_cache_for_key(public_count_cache_key) do
- public_count
- end
+ def issues_without_hidden_without_confidential
+ self.class.query(@project, public_only: true, include_hidden: false).count
+ end
- update_cache_for_key(total_count_cache_key) do
- total_count
- end
- end
+ def issues_without_hidden_with_confidential
+ self.class.query(@project, public_only: false, include_hidden: false).count
end
- # rubocop: enable CodeReuse/ActiveRecord
- # We only show total issues count for reporters
- # which are allowed to view confidential issues
+ # We only show total issues count for admins, who are allowed to view hidden issues.
+ # We also only show issues count including confidential for reporters, who are allowed to view confidential issues.
# This will still show a discrepancy on issues number but should be less than before.
# Check https://gitlab.com/gitlab-org/gitlab-foss/issues/38418 description.
# rubocop: disable CodeReuse/ActiveRecord
- def self.query(projects, public_only: true)
- issues_filtered_by_type = Issue.opened.with_issue_type(Issue::TYPES_FOR_LIST)
- if public_only
- issues_filtered_by_type.public_only.where(project: projects)
+ def self.query(projects, public_only: true, include_hidden: false)
+ if include_hidden
+ Issue.opened.with_issue_type(Issue::TYPES_FOR_LIST).where(project: projects)
+ elsif public_only
+ Issue.public_only.opened.with_issue_type(Issue::TYPES_FOR_LIST).where(project: projects)
else
- issues_filtered_by_type.where(project: projects)
+ Issue.without_hidden.opened.with_issue_type(Issue::TYPES_FOR_LIST).where(project: projects)
end
end
# rubocop: enable CodeReuse/ActiveRecord