diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/assets/javascripts/vue_shared/components/file_row.vue | 6 | ||||
-rw-r--r-- | app/assets/javascripts/vue_shared/components/file_row_header.vue | 2 | ||||
-rw-r--r-- | app/finders/issuable_finder.rb | 381 | ||||
-rw-r--r-- | app/finders/issuable_finder/params.rb | 287 | ||||
-rw-r--r-- | app/finders/issues_finder.rb | 86 | ||||
-rw-r--r-- | app/finders/issues_finder/params.rb | 53 | ||||
-rw-r--r-- | app/models/merge_request.rb | 2 | ||||
-rw-r--r-- | app/services/issuable/bulk_update_service.rb | 2 | ||||
-rw-r--r-- | app/services/issuable_base_service.rb | 4 | ||||
-rw-r--r-- | app/views/admin/services/index.html.haml | 2 | ||||
-rw-r--r-- | app/views/projects/services/_index.html.haml | 2 | ||||
-rw-r--r-- | app/views/projects/services/edit.html.haml | 2 |
12 files changed, 434 insertions, 395 deletions
diff --git a/app/assets/javascripts/vue_shared/components/file_row.vue b/app/assets/javascripts/vue_shared/components/file_row.vue index 4d60cf5b1cc..e3a606571c0 100644 --- a/app/assets/javascripts/vue_shared/components/file_row.vue +++ b/app/assets/javascripts/vue_shared/components/file_row.vue @@ -39,6 +39,10 @@ export default { 'is-open': this.file.opened, }; }, + textForTitle() { + // don't output a title if we don't have the expanded path + return this.file?.tree?.length ? this.file.tree[0].parentPath : false; + }, }, watch: { 'file.active': function fileActiveWatch(active) { @@ -106,7 +110,7 @@ export default { <div v-else :class="fileClass" - :title="file.name" + :title="textForTitle" class="file-row" role="button" @click="clickFile" diff --git a/app/assets/javascripts/vue_shared/components/file_row_header.vue b/app/assets/javascripts/vue_shared/components/file_row_header.vue index 301fd8116a9..2c3e2a3a433 100644 --- a/app/assets/javascripts/vue_shared/components/file_row_header.vue +++ b/app/assets/javascripts/vue_shared/components/file_row_header.vue @@ -19,7 +19,7 @@ export default { </script> <template> - <div class="file-row-header bg-white sticky-top p-2 js-file-row-header"> + <div class="file-row-header bg-white sticky-top p-2 js-file-row-header" :title="path"> <span class="bold">{{ truncatedPath }}</span> </div> </template> diff --git a/app/finders/issuable_finder.rb b/app/finders/issuable_finder.rb index 6d5b1ca3bc5..5687b375cf0 100644 --- a/app/finders/issuable_finder.rb +++ b/app/finders/issuable_finder.rb @@ -38,19 +38,14 @@ class IssuableFinder include CreatedAtFilter include Gitlab::Utils::StrongMemoize - requires_cross_project_access unless: -> { project? } - - # This is used as a common filter for None / Any - FILTER_NONE = 'none' - FILTER_ANY = 'any' - - # This is used in unassigning users - NONE = '0' + requires_cross_project_access unless: -> { params.project? } NEGATABLE_PARAMS_HELPER_KEYS = %i[include_subgroups in].freeze attr_accessor :current_user, :params + delegate(*%i[assignee milestones], to: :params) + class << self def scalar_params @scalar_params ||= %i[ @@ -91,9 +86,13 @@ class IssuableFinder end end + def params_class + IssuableFinder::Params + end + def initialize(current_user, params = {}) @current_user = current_user - @params = params + @params = params_class.new(params, current_user, klass) end def execute @@ -161,7 +160,7 @@ class IssuableFinder # of a CTE. The CTE will not be used if the sort doesn't support it, # but will always be used for the counts here as we ignore sorting # anyway. - labels_count = label_names.any? ? label_names.count : 1 + labels_count = params.label_names.any? ? params.label_names.count : 1 labels_count = 1 if use_cte_for_search? finder.execute.reorder(nil).group(:state_id).count.each do |key, value| @@ -174,192 +173,10 @@ class IssuableFinder end # rubocop: enable CodeReuse/ActiveRecord - def group - return @group if defined?(@group) - - @group = - if params[:group_id].present? - Group.find(params[:group_id]) - else - nil - end - end - - def related_groups - if project? && project && project.group && Ability.allowed?(current_user, :read_group, project.group) - project.group.self_and_ancestors - elsif group - [group] - elsif current_user - Gitlab::ObjectHierarchy.new(current_user.authorized_groups, current_user.groups).all_objects - else - [] - end - end - - def project? - params[:project_id].present? - end - - def project - return @project if defined?(@project) - - project = Project.find(params[:project_id]) - project = nil unless Ability.allowed?(current_user, :"read_#{klass.to_ability_name}", project) - - @project = project - end - - def projects - return @projects if defined?(@projects) - - return @projects = [project] if project? - - projects = - if current_user && params[:authorized_only].presence && !current_user_related? - current_user.authorized_projects(min_access_level) - else - projects_public_or_visible_to_user - end - - @projects = projects.with_feature_available_for_user(klass, current_user).reorder(nil) # rubocop: disable CodeReuse/ActiveRecord - end - - def projects_public_or_visible_to_user - projects = - if group - if params[:projects] - find_group_projects.id_in(params[:projects]) - else - find_group_projects - end - elsif params[:projects] - Project.id_in(params[:projects]) - else - Project - end - - projects.public_or_visible_to_user(current_user, min_access_level) - end - - def find_group_projects - return Project.none unless group - - if params[:include_subgroups] - Project.where(namespace_id: group.self_and_descendants) # rubocop: disable CodeReuse/ActiveRecord - else - group.projects - end - end - def search params[:search].presence end - def milestones? - params[:milestone_title].present? - end - - def milestones - return @milestones if defined?(@milestones) - - @milestones = - if milestones? - if project? - group_id = project.group&.id - project_id = project.id - end - - group_id = group.id if group - - search_params = - { title: params[:milestone_title], project_ids: project_id, group_ids: group_id } - - MilestonesFinder.new(search_params).execute # rubocop: disable CodeReuse/Finder - else - Milestone.none - end - end - - def labels? - params[:label_name].present? - end - - def filter_by_no_label? - downcased = label_names.map(&:downcase) - - downcased.include?(FILTER_NONE) - end - - def filter_by_any_label? - label_names.map(&:downcase).include?(FILTER_ANY) - end - - def labels - return @labels if defined?(@labels) - - @labels = - if labels? && !filter_by_no_label? - LabelsFinder.new(current_user, project_ids: projects, title: label_names).execute(skip_authorization: true) # rubocop: disable CodeReuse/Finder - else - Label.none - end - end - - def assignee_id? - params[:assignee_id].present? - end - - def assignee_username? - params[:assignee_username].present? - end - - def assignee - assignees.first - end - - # rubocop: disable CodeReuse/ActiveRecord - def assignees - strong_memoize(:assignees) do - if assignee_id? - User.where(id: params[:assignee_id]) - elsif assignee_username? - User.where(username: params[:assignee_username]) - else - User.none - end - end - end - # rubocop: enable CodeReuse/ActiveRecord - - def author_id? - params[:author_id].present? && params[:author_id] != NONE - end - - def author_username? - params[:author_username].present? && params[:author_username] != NONE - end - - def no_author? - # author_id takes precedence over author_username - params[:author_id] == NONE || params[:author_username] == NONE - end - - # rubocop: disable CodeReuse/ActiveRecord - def author - return @author if defined?(@author) - - @author = - if author_id? - User.find_by(id: params[:author_id]) - elsif author_username? - User.find_by_username(params[:author_username]) - else - nil - end - end - # rubocop: enable CodeReuse/ActiveRecord - def use_cte_for_search? strong_memoize(:use_cte_for_search) do next false unless search @@ -370,10 +187,6 @@ class IssuableFinder end end - def releases? - params[:release_tag].present? - end - private def force_cte? @@ -431,7 +244,7 @@ class IssuableFinder # rubocop: disable CodeReuse/ActiveRecord def by_scope(items) - return items.none if current_user_related? && !current_user + return items.none if params.current_user_related? && !current_user case params[:scope] when 'created_by_me', 'authored' @@ -480,16 +293,13 @@ class IssuableFinder # rubocop: disable CodeReuse/ActiveRecord def by_project(items) - items = - if project? - items.of_projects(projects).references_project - elsif projects - items.merge(projects.reorder(nil)).join_project - else - items.none - end - - items + if params.project? + items.of_projects(params.projects).references_project + elsif params.projects + items.merge(params.projects.reorder(nil)).join_project + else + items.none + end end # rubocop: enable CodeReuse/ActiveRecord @@ -519,42 +329,34 @@ class IssuableFinder def sort(items) # Ensure we always have an explicit sort order (instead of inheriting # multiple orders when combining ActiveRecord::Relation objects). - params[:sort] ? items.sort_by_attribute(params[:sort], excluded_labels: label_names) : items.reorder(id: :desc) + params[:sort] ? items.sort_by_attribute(params[:sort], excluded_labels: params.label_names) : items.reorder(id: :desc) end # rubocop: enable CodeReuse/ActiveRecord - def filter_by_no_assignee? - params[:assignee_id].to_s.downcase == FILTER_NONE - end - - def filter_by_any_assignee? - params[:assignee_id].to_s.downcase == FILTER_ANY - end - # rubocop: disable CodeReuse/ActiveRecord def by_author(items) - if author - items = items.where(author_id: author.id) - elsif no_author? - items = items.where(author_id: nil) - elsif author_id? || author_username? # author not found - items = items.none + if params.author + items.where(author_id: params.author.id) + elsif params.no_author? + items.where(author_id: nil) + elsif params.author_id? || params.author_username? # author not found + items.none + else + items end - - items end # rubocop: enable CodeReuse/ActiveRecord def by_assignee(items) - return items.assigned_to(assignees) if not_query? && assignees.any? + return items.assigned_to(params.assignees) if not_query? && params.assignees.any? - if filter_by_no_assignee? + if params.filter_by_no_assignee? items.unassigned - elsif filter_by_any_assignee? + elsif params.filter_by_any_assignee? items.assigned - elsif assignee - items.assigned_to(assignee) - elsif assignee_id? || assignee_username? # assignee not found + elsif params.assignee + items.assigned_to(params.assignee) + elsif params.assignee_id? || params.assignee_username? # assignee not found items.none else items @@ -563,106 +365,56 @@ class IssuableFinder # rubocop: disable CodeReuse/ActiveRecord def by_milestone(items) - if milestones? - if filter_by_no_milestone? - items = items.left_joins_milestones.where(milestone_id: [-1, nil]) - elsif filter_by_any_milestone? - items = items.any_milestone - elsif filter_by_upcoming_milestone? - upcoming_ids = Milestone.upcoming_ids(projects, related_groups) - items = items.left_joins_milestones.where(milestone_id: upcoming_ids) - elsif filter_by_started_milestone? - items = items.left_joins_milestones.merge(Milestone.started) - else - items = items.with_milestone(params[:milestone_title]) - end + return items unless params.milestones? + + if params.filter_by_no_milestone? + items.left_joins_milestones.where(milestone_id: [-1, nil]) + elsif params.filter_by_any_milestone? + items.any_milestone + elsif params.filter_by_upcoming_milestone? + upcoming_ids = Milestone.upcoming_ids(params.projects, params.related_groups) + items.left_joins_milestones.where(milestone_id: upcoming_ids) + elsif params.filter_by_started_milestone? + items.left_joins_milestones.merge(Milestone.started) + else + items.with_milestone(params[:milestone_title]) end - - items end # rubocop: enable CodeReuse/ActiveRecord def by_release(items) - return items unless releases? + return items unless params.releases? - if filter_by_no_release? + if params.filter_by_no_release? items.without_release - elsif filter_by_any_release? + elsif params.filter_by_any_release? items.any_release else items.with_release(params[:release_tag], params[:project_id]) end end - def filter_by_no_milestone? - # Accepts `No Milestone` for compatibility - params[:milestone_title].to_s.downcase == FILTER_NONE || params[:milestone_title] == Milestone::None.title - end - - def filter_by_any_milestone? - # Accepts `Any Milestone` for compatibility - params[:milestone_title].to_s.downcase == FILTER_ANY || params[:milestone_title] == Milestone::Any.title - end - - def filter_by_upcoming_milestone? - params[:milestone_title] == Milestone::Upcoming.name - end - - def filter_by_started_milestone? - params[:milestone_title] == Milestone::Started.name - end - - def filter_by_no_release? - params[:release_tag].to_s.downcase == FILTER_NONE - end - - def filter_by_any_release? - params[:release_tag].to_s.downcase == FILTER_ANY - end - def by_label(items) - return items unless labels? - - items = - if filter_by_no_label? - items.without_label - elsif filter_by_any_label? - items.any_label - else - items.with_label(label_names, params[:sort], not_query: not_query?) - end + return items unless params.labels? - items - end - - def by_my_reaction_emoji(items) - if params[:my_reaction_emoji].present? && current_user - items = - if filter_by_no_reaction? - items.not_awarded(current_user) - elsif filter_by_any_reaction? - items.awarded(current_user) - else - items.awarded(current_user, params[:my_reaction_emoji]) - end + if params.filter_by_no_label? + items.without_label + elsif params.filter_by_any_label? + items.any_label + else + items.with_label(params.label_names, params[:sort], not_query: not_query?) end - - items - end - - def filter_by_no_reaction? - params[:my_reaction_emoji].to_s.downcase == FILTER_NONE end - def filter_by_any_reaction? - params[:my_reaction_emoji].to_s.downcase == FILTER_ANY - end + def by_my_reaction_emoji(items) + return items unless params[:my_reaction_emoji] && current_user - def label_names - if labels? - params[:label_name].is_a?(String) ? params[:label_name].split(',') : params[:label_name] + if params.filter_by_no_reaction? + items.not_awarded(current_user) + elsif params.filter_by_any_reaction? + items.awarded(current_user) else - [] + items.awarded(current_user, params[:my_reaction_emoji]) end end @@ -670,15 +422,6 @@ class IssuableFinder params[:non_archived].present? ? items.non_archived : items end - def current_user_related? - scope = params[:scope] - scope == 'created_by_me' || scope == 'authored' || scope == 'assigned_to_me' - end - - def min_access_level - ProjectFeature.required_minimum_access_level(klass) - end - def not_query? !!params[:not_query] end diff --git a/app/finders/issuable_finder/params.rb b/app/finders/issuable_finder/params.rb new file mode 100644 index 00000000000..120ef364368 --- /dev/null +++ b/app/finders/issuable_finder/params.rb @@ -0,0 +1,287 @@ +# frozen_string_literal: true + +class IssuableFinder + class Params < SimpleDelegator + include Gitlab::Utils::StrongMemoize + + # This is used as a common filter for None / Any + FILTER_NONE = 'none' + FILTER_ANY = 'any' + + # This is used in unassigning users + NONE = '0' + + alias_method :params, :__getobj__ + + attr_accessor :current_user, :klass + + def initialize(params, current_user, klass) + @current_user = current_user + @klass = klass + # We turn the params into a HashWithIndifferentAccess. We must use #to_h first because sometimes + # we get ActionController::Params and IssuableFinder::Params objects here. + super(params.to_h.with_indifferent_access) + end + + def present? + params.present? + end + + def author_id? + params[:author_id].present? && params[:author_id] != NONE + end + + def author_username? + params[:author_username].present? && params[:author_username] != NONE + end + + def no_author? + # author_id takes precedence over author_username + params[:author_id] == NONE || params[:author_username] == NONE + end + + def filter_by_no_assignee? + params[:assignee_id].to_s.downcase == FILTER_NONE + end + + def filter_by_any_assignee? + params[:assignee_id].to_s.downcase == FILTER_ANY + end + + def filter_by_no_label? + downcased = label_names.map(&:downcase) + + downcased.include?(FILTER_NONE) + end + + def filter_by_any_label? + label_names.map(&:downcase).include?(FILTER_ANY) + end + + def labels? + params[:label_name].present? + end + + def milestones? + params[:milestone_title].present? + end + + def filter_by_no_milestone? + # Accepts `No Milestone` for compatibility + params[:milestone_title].to_s.downcase == FILTER_NONE || params[:milestone_title] == Milestone::None.title + end + + def filter_by_any_milestone? + # Accepts `Any Milestone` for compatibility + params[:milestone_title].to_s.downcase == FILTER_ANY || params[:milestone_title] == Milestone::Any.title + end + + def filter_by_upcoming_milestone? + params[:milestone_title] == Milestone::Upcoming.name + end + + def filter_by_started_milestone? + params[:milestone_title] == Milestone::Started.name + end + + def filter_by_no_release? + params[:release_tag].to_s.downcase == FILTER_NONE + end + + def filter_by_any_release? + params[:release_tag].to_s.downcase == FILTER_ANY + end + + def filter_by_no_reaction? + params[:my_reaction_emoji].to_s.downcase == FILTER_NONE + end + + def filter_by_any_reaction? + params[:my_reaction_emoji].to_s.downcase == FILTER_ANY + end + + def releases? + params[:release_tag].present? + end + + def project? + params[:project_id].present? + end + + def group + strong_memoize(:group) do + if params[:group_id].present? + Group.find(params[:group_id]) + else + nil + end + end + end + + def related_groups + if project? && project&.group && Ability.allowed?(current_user, :read_group, project.group) + project.group.self_and_ancestors + elsif group + [group] + elsif current_user + Gitlab::ObjectHierarchy.new(current_user.authorized_groups, current_user.groups).all_objects + else + [] + end + end + + def project + strong_memoize(:project) do + project = Project.find(params[:project_id]) + project = nil unless Ability.allowed?(current_user, :"read_#{klass.to_ability_name}", project) + + project + end + end + + def projects + strong_memoize(:projects) do + next [project] if project? + + projects = + if current_user && params[:authorized_only].presence && !current_user_related? + current_user.authorized_projects(min_access_level) + else + projects_public_or_visible_to_user + end + + projects.with_feature_available_for_user(klass, current_user).reorder(nil) # rubocop: disable CodeReuse/ActiveRecord + end + end + + # rubocop: disable CodeReuse/ActiveRecord + def author + strong_memoize(:author) do + if author_id? + User.find_by(id: params[:author_id]) + elsif author_username? + User.find_by_username(params[:author_username]) + else + nil + end + end + end + # rubocop: enable CodeReuse/ActiveRecord + + # rubocop: disable CodeReuse/ActiveRecord + def assignees + strong_memoize(:assignees) do + if assignee_id? + User.where(id: params[:assignee_id]) + elsif assignee_username? + User.where(username: params[:assignee_username]) + else + User.none + end + end + end + # rubocop: enable CodeReuse/ActiveRecord + + def assignee + assignees.first + end + + def label_names + if labels? + params[:label_name].is_a?(String) ? params[:label_name].split(',') : params[:label_name] + else + [] + end + end + + def labels + strong_memoize(:labels) do + if labels? && !filter_by_no_label? + LabelsFinder.new(current_user, project_ids: projects, title: label_names).execute(skip_authorization: true) # rubocop: disable CodeReuse/Finder + else + Label.none + end + end + end + + def milestones + strong_memoize(:milestones) do + if milestones? + if project? + group_id = project.group&.id + project_id = project.id + end + + group_id = group.id if group + + search_params = + { title: params[:milestone_title], project_ids: project_id, group_ids: group_id } + + MilestonesFinder.new(search_params).execute # rubocop: disable CodeReuse/Finder + else + Milestone.none + end + end + end + + def current_user_related? + scope = params[:scope] + scope == 'created_by_me' || scope == 'authored' || scope == 'assigned_to_me' + end + + def find_group_projects + return Project.none unless group + + if params[:include_subgroups] + Project.where(namespace_id: group.self_and_descendants) # rubocop: disable CodeReuse/ActiveRecord + else + group.projects + end + end + + # We use Hash#merge in a few places, so let's support it + def merge(other) + self.class.new(params.merge(other), current_user, klass) + end + + # Just for symmetry, and in case someone tries to use it + def merge!(other) + params.merge!(other) + end + + private + + def projects_public_or_visible_to_user + projects = + if group + if params[:projects] + find_group_projects.id_in(params[:projects]) + else + find_group_projects + end + elsif params[:projects] + Project.id_in(params[:projects]) + else + Project + end + + projects.public_or_visible_to_user(current_user, min_access_level) + end + + def min_access_level + ProjectFeature.required_minimum_access_level(klass) + end + + def method_missing(method_name, *args, &block) + if method_name[-1] == '?' + params[method_name[0..-2].to_sym].present? + else + super + end + end + + def respond_to_missing?(method_name, include_private = false) + method_name[-1] == '?' + end + end +end diff --git a/app/finders/issues_finder.rb b/app/finders/issues_finder.rb index 641b4422db9..72695a9d501 100644 --- a/app/finders/issues_finder.rb +++ b/app/finders/issues_finder.rb @@ -38,10 +38,14 @@ class IssuesFinder < IssuableFinder end # rubocop: enable CodeReuse/ActiveRecord + def params_class + IssuesFinder::Params + end + # rubocop: disable CodeReuse/ActiveRecord def with_confidentiality_access_check - return Issue.all if user_can_see_all_confidential_issues? - return Issue.where('issues.confidential IS NOT TRUE') if user_cannot_see_confidential_issues? + return Issue.all if params.user_can_see_all_confidential_issues? + return Issue.where('issues.confidential IS NOT TRUE') if params.user_cannot_see_confidential_issues? Issue.where(' issues.confidential IS NOT TRUE @@ -57,17 +61,13 @@ class IssuesFinder < IssuableFinder private def init_collection - if public_only? + if params.public_only? Issue.public_only else with_confidentiality_access_check end end - def public_only? - params.fetch(:public_only, false) - end - def filter_items(items) issues = super issues = by_due_date(issues) @@ -82,67 +82,19 @@ class IssuesFinder < IssuableFinder end def by_due_date(items) - if due_date? - if filter_by_no_due_date? - items = items.without_due_date - elsif filter_by_overdue? - items = items.due_before(Date.today) - elsif filter_by_due_this_week? - items = items.due_between(Date.today.beginning_of_week, Date.today.end_of_week) - elsif filter_by_due_this_month? - items = items.due_between(Date.today.beginning_of_month, Date.today.end_of_month) - elsif filter_by_due_next_month_and_previous_two_weeks? - items = items.due_between(Date.today - 2.weeks, (Date.today + 1.month).end_of_month) - end + return items unless params.due_date? + + if params.filter_by_no_due_date? + items.without_due_date + elsif params.filter_by_overdue? + items.due_before(Date.today) + elsif params.filter_by_due_this_week? + items.due_between(Date.today.beginning_of_week, Date.today.end_of_week) + elsif params.filter_by_due_this_month? + items.due_between(Date.today.beginning_of_month, Date.today.end_of_month) + elsif params.filter_by_due_next_month_and_previous_two_weeks? + items.due_between(Date.today - 2.weeks, (Date.today + 1.month).end_of_month) end - - items - end - - def filter_by_no_due_date? - due_date? && params[:due_date] == Issue::NoDueDate.name - end - - def filter_by_overdue? - due_date? && params[:due_date] == Issue::Overdue.name - end - - def filter_by_due_this_week? - due_date? && params[:due_date] == Issue::DueThisWeek.name - end - - def filter_by_due_this_month? - due_date? && params[:due_date] == Issue::DueThisMonth.name - end - - def filter_by_due_next_month_and_previous_two_weeks? - due_date? && params[:due_date] == Issue::DueNextMonthAndPreviousTwoWeeks.name - end - - def due_date? - params[:due_date].present? - end - - def user_can_see_all_confidential_issues? - return @user_can_see_all_confidential_issues if defined?(@user_can_see_all_confidential_issues) - - return @user_can_see_all_confidential_issues = false if current_user.blank? - return @user_can_see_all_confidential_issues = true if current_user.can_read_all_resources? - - @user_can_see_all_confidential_issues = - if project? && project - project.team.max_member_access(current_user.id) >= CONFIDENTIAL_ACCESS_LEVEL - elsif group - group.max_member_access_for_user(current_user) >= CONFIDENTIAL_ACCESS_LEVEL - else - false - end - end - - def user_cannot_see_confidential_issues? - return false if user_can_see_all_confidential_issues? - - current_user.blank? end end diff --git a/app/finders/issues_finder/params.rb b/app/finders/issues_finder/params.rb new file mode 100644 index 00000000000..aaeead7c709 --- /dev/null +++ b/app/finders/issues_finder/params.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +class IssuesFinder + class Params < IssuableFinder::Params + def public_only? + params.fetch(:public_only, false) + end + + def filter_by_no_due_date? + due_date? && params[:due_date] == Issue::NoDueDate.name + end + + def filter_by_overdue? + due_date? && params[:due_date] == Issue::Overdue.name + end + + def filter_by_due_this_week? + due_date? && params[:due_date] == Issue::DueThisWeek.name + end + + def filter_by_due_this_month? + due_date? && params[:due_date] == Issue::DueThisMonth.name + end + + def filter_by_due_next_month_and_previous_two_weeks? + due_date? && params[:due_date] == Issue::DueNextMonthAndPreviousTwoWeeks.name + end + + def user_can_see_all_confidential_issues? + return @user_can_see_all_confidential_issues if defined?(@user_can_see_all_confidential_issues) + + return @user_can_see_all_confidential_issues = false if current_user.blank? + return @user_can_see_all_confidential_issues = true if current_user.can_read_all_resources? + + @user_can_see_all_confidential_issues = + if project? && project + project.team.max_member_access(current_user.id) >= CONFIDENTIAL_ACCESS_LEVEL + elsif group + group.max_member_access_for_user(current_user) >= CONFIDENTIAL_ACCESS_LEVEL + else + false + end + end + + def user_cannot_see_confidential_issues? + return false if user_can_see_all_confidential_issues? + + current_user.blank? + end + end +end + +IssuableFinder::Params.prepend_if_ee('EE::IssuesFinder::Params') diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 2a6f498269c..7934b0f8f59 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -189,7 +189,7 @@ class MergeRequest < ApplicationRecord end # rubocop: disable CodeReuse/ServiceClass - after_transition [:unchecked, :checking] => :cannot_be_merged do |merge_request, transition| + after_transition unchecked: :cannot_be_merged do |merge_request, transition| if merge_request.notify_conflict? NotificationService.new.merge_request_unmergeable(merge_request) TodoService.new.merge_request_became_unmergeable(merge_request) diff --git a/app/services/issuable/bulk_update_service.rb b/app/services/issuable/bulk_update_service.rb index bbb3c2ad050..2cd0e1e992d 100644 --- a/app/services/issuable/bulk_update_service.rb +++ b/app/services/issuable/bulk_update_service.rb @@ -21,7 +21,7 @@ module Issuable params.delete(key) unless params[key].present? end - if params[:assignee_ids] == [IssuableFinder::NONE.to_s] + if params[:assignee_ids] == [IssuableFinder::Params::NONE.to_s] params[:assignee_ids] = [] end diff --git a/app/services/issuable_base_service.rb b/app/services/issuable_base_service.rb index 830afbf4a43..506f4309a1e 100644 --- a/app/services/issuable_base_service.rb +++ b/app/services/issuable_base_service.rb @@ -46,7 +46,7 @@ class IssuableBaseService < BaseService assignee_ids = params[:assignee_ids].select { |assignee_id| assignee_can_read?(issuable, assignee_id) } - if params[:assignee_ids].map(&:to_s) == [IssuableFinder::NONE] + if params[:assignee_ids].map(&:to_s) == [IssuableFinder::Params::NONE] params[:assignee_ids] = [] elsif assignee_ids.any? params[:assignee_ids] = assignee_ids @@ -70,7 +70,7 @@ class IssuableBaseService < BaseService milestone_id = params[:milestone_id] return unless milestone_id - params[:milestone_id] = '' if milestone_id == IssuableFinder::NONE + params[:milestone_id] = '' if milestone_id == IssuableFinder::Params::NONE groups = project.group&.self_and_ancestors&.select(:id) milestone = diff --git a/app/views/admin/services/index.html.haml b/app/views/admin/services/index.html.haml index 48f31bd0c6e..e0a1a3549a5 100644 --- a/app/views/admin/services/index.html.haml +++ b/app/views/admin/services/index.html.haml @@ -1,6 +1,6 @@ - page_title "Service Templates" %h3.page-title Service templates -%p.light Service template allows you to set default values for project services +%p.light= s_('AdminSettings|Service template allows you to set default values for integrations') .table-holder %table.table diff --git a/app/views/projects/services/_index.html.haml b/app/views/projects/services/_index.html.haml index a4041d09415..dca324ac846 100644 --- a/app/views/projects/services/_index.html.haml +++ b/app/views/projects/services/_index.html.haml @@ -13,7 +13,7 @@ %thead %tr %th - %th= s_("ProjectService|Service") + %th= _('Integration') %th.d-none.d-sm-block= _("Description") %th= s_("ProjectService|Last edit") - @services.sort_by(&:title).each do |service| diff --git a/app/views/projects/services/edit.html.haml b/app/views/projects/services/edit.html.haml index ef799d2c046..4195dce7780 100644 --- a/app/views/projects/services/edit.html.haml +++ b/app/views/projects/services/edit.html.haml @@ -1,6 +1,6 @@ - breadcrumb_title @service.title - add_to_breadcrumbs _('Integration Settings'), project_settings_integrations_path(@project) -- page_title @service.title, s_("ProjectService|Services") +- page_title @service.title, _('Integrations') = render 'deprecated_message' if @service.deprecation_message |