From b76ae638462ab0f673e5915986070518dd3f9ad3 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Thu, 19 Aug 2021 09:08:42 +0000 Subject: Add latest changes from gitlab-org/gitlab@14-2-stable-ee --- app/helpers/admin/user_actions_helper.rb | 4 +- app/helpers/analytics/navbar_helper.rb | 28 ------ app/helpers/application_helper.rb | 6 ++ app/helpers/application_settings_helper.rb | 6 ++ app/helpers/boards_helper.rb | 8 -- app/helpers/button_helper.rb | 6 +- app/helpers/ci/pipeline_editor_helper.rb | 4 +- app/helpers/clusters_helper.rb | 3 +- app/helpers/commits_helper.rb | 2 +- app/helpers/compare_helper.rb | 6 +- app/helpers/dashboard_helper.rb | 4 - app/helpers/diff_helper.rb | 8 +- app/helpers/emails_helper.rb | 34 ++++--- app/helpers/environment_helper.rb | 27 ++++++ app/helpers/environments_helper.rb | 8 ++ app/helpers/groups/group_members_helper.rb | 4 +- app/helpers/groups_helper.rb | 106 ++++----------------- app/helpers/ide_helper.rb | 2 +- app/helpers/integrations_helper.rb | 19 ++++ app/helpers/invite_members_helper.rb | 64 ++++++++++--- .../issuables_description_templates_helper.rb | 7 +- app/helpers/issues_helper.rb | 14 ++- app/helpers/markup_helper.rb | 2 +- app/helpers/merge_requests_helper.rb | 5 +- app/helpers/nav/new_dropdown_helper.rb | 2 +- app/helpers/nav_helper.rb | 9 -- app/helpers/packages_helper.rb | 5 +- app/helpers/projects/project_members_helper.rb | 28 +----- app/helpers/projects/terraform_helper.rb | 5 +- app/helpers/projects_helper.rb | 59 ++++++------ app/helpers/search_helper.rb | 4 +- app/helpers/snippets_helper.rb | 6 ++ app/helpers/sorting_helper.rb | 10 +- app/helpers/sorting_titles_values_helper.rb | 24 +++++ app/helpers/time_zone_helper.rb | 5 + app/helpers/tree_helper.rb | 2 +- app/helpers/user_callouts_helper.rb | 13 +-- app/helpers/users_helper.rb | 2 +- 38 files changed, 285 insertions(+), 266 deletions(-) delete mode 100644 app/helpers/analytics/navbar_helper.rb (limited to 'app/helpers') diff --git a/app/helpers/admin/user_actions_helper.rb b/app/helpers/admin/user_actions_helper.rb index 5719d8f5ffd..dc31c06477e 100644 --- a/app/helpers/admin/user_actions_helper.rb +++ b/app/helpers/admin/user_actions_helper.rb @@ -48,9 +48,9 @@ module Admin end def delete_actions - return unless can?(current_user, :destroy_user, @user) && !@user.blocked_pending_approval? && @user.can_be_removed? + return unless can?(current_user, :destroy_user, @user) && !@user.blocked_pending_approval? - @actions << 'delete' + @actions << 'delete' if @user.can_be_removed? @actions << 'delete_with_contributions' end diff --git a/app/helpers/analytics/navbar_helper.rb b/app/helpers/analytics/navbar_helper.rb deleted file mode 100644 index 091571ff15a..00000000000 --- a/app/helpers/analytics/navbar_helper.rb +++ /dev/null @@ -1,28 +0,0 @@ -# frozen_string_literal: true - -module Analytics - module NavbarHelper - class NavbarSubItem - attr_reader :title, :path, :link, :link_to_options - - def initialize(title:, path:, link:, link_to_options: {}) - @title = title - @path = path - @link = link - @link_to_options = link_to_options.merge(title: title) - end - end - - def group_analytics_navbar_links(group, current_user) - [] - end - - private - - def navbar_sub_item(args) - NavbarSubItem.new(**args) - end - end -end - -Analytics::NavbarHelper.prepend_mod_with('Analytics::NavbarHelper') diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 1304bcb1c7e..58f933a7fe0 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -413,6 +413,12 @@ module ApplicationHelper end end + def gitlab_ui_form_for(record, *args, &block) + options = args.extract_options! + + form_for(record, *(args << options.merge({ builder: ::Gitlab::FormBuilders::GitlabUiFormBuilder })), &block) + end + private def appearance diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb index a3df566e4b3..2447a731167 100644 --- a/app/helpers/application_settings_helper.rb +++ b/app/helpers/application_settings_helper.rb @@ -447,6 +447,12 @@ module ApplicationSettingsHelper def signup_enabled? !!Gitlab::CurrentSettings.signup_enabled end + + def pending_user_count + return 0 if Gitlab::CurrentSettings.new_user_signups_cap.blank? + + User.blocked_pending_approval.count + end end ApplicationSettingsHelper.prepend_mod_with('ApplicationSettingsHelper') diff --git a/app/helpers/boards_helper.rb b/app/helpers/boards_helper.rb index f72f8bfd151..33d5bae88f4 100644 --- a/app/helpers/boards_helper.rb +++ b/app/helpers/boards_helper.rb @@ -119,14 +119,6 @@ module BoardsHelper } end - def boards_link_text - if current_board_parent.multiple_issue_boards_available? - s_("IssueBoards|Boards") - else - s_("IssueBoards|Board") - end - end - def recent_boards_path recent_project_boards_path(@project) if current_board_parent.is_a?(Project) end diff --git a/app/helpers/button_helper.rb b/app/helpers/button_helper.rb index 27d6ee57d8b..eb30ffc0093 100644 --- a/app/helpers/button_helper.rb +++ b/app/helpers/button_helper.rb @@ -22,7 +22,7 @@ module ButtonHelper def clipboard_button(data = {}) css_class = data[:class] || 'btn-clipboard btn-transparent' title = data[:title] || _('Copy') - button_text = data[:button_text] || '' + button_text = data[:button_text] || nil hide_tooltip = data[:hide_tooltip] || false hide_button_icon = data[:hide_button_icon] || false item_prop = data[:itemprop] || nil @@ -55,8 +55,8 @@ module ButtonHelper } content_tag :button, button_attributes do - concat(sprite_icon('copy-to-clipboard')) unless hide_button_icon - concat(button_text) + concat(sprite_icon('copy-to-clipboard', css_class: ['gl-icon', *('gl-button-icon' unless button_text.nil?)].join(' '))) unless hide_button_icon + concat(content_tag(:span, button_text, class: 'gl-button-text')) unless button_text.nil? end end diff --git a/app/helpers/ci/pipeline_editor_helper.rb b/app/helpers/ci/pipeline_editor_helper.rb index d441ffbb853..4dfe136c206 100644 --- a/app/helpers/ci/pipeline_editor_helper.rb +++ b/app/helpers/ci/pipeline_editor_helper.rb @@ -21,7 +21,7 @@ module Ci "empty-state-illustration-path" => image_path('illustrations/empty-state/empty-dag-md.svg'), "initial-branch-name" => initial_branch, "lint-help-page-path" => help_page_path('ci/lint', anchor: 'validate-basic-logic-and-syntax'), - "needs-help-page-path" => help_page_path('ci/yaml/README', anchor: 'needs'), + "needs-help-page-path" => help_page_path('ci/yaml/index', anchor: 'needs'), "new-merge-request-path" => namespace_project_new_merge_request_path, "pipeline_etag" => latest_commit ? graphql_etag_pipeline_sha_path(commit_sha) : '', "pipeline-page-path" => project_pipelines_path(project), @@ -30,7 +30,7 @@ module Ci "project-namespace" => project.namespace.full_path, "runner-help-page-path" => help_page_path('ci/runners/index'), "total-branches" => project.repository.branches.length, - "yml-help-page-path" => help_page_path('ci/yaml/README') + "yml-help-page-path" => help_page_path('ci/yaml/index') } end end diff --git a/app/helpers/clusters_helper.rb b/app/helpers/clusters_helper.rb index e9a75babb97..c355fa5cc67 100644 --- a/app/helpers/clusters_helper.rb +++ b/app/helpers/clusters_helper.rb @@ -24,7 +24,8 @@ module ClustersHelper agent_docs_url: help_page_path('user/clusters/agent/index'), install_docs_url: help_page_path('administration/clusters/kas'), get_started_docs_url: help_page_path('user/clusters/agent/index', anchor: 'define-a-configuration-repository'), - integration_docs_url: help_page_path('user/clusters/agent/index', anchor: 'get-started-with-gitops-and-the-gitlab-agent') + integration_docs_url: help_page_path('user/clusters/agent/index', anchor: 'get-started-with-gitops-and-the-gitlab-agent'), + kas_address: Gitlab::Kas.external_url } end diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb index d2ac1e8f985..53017beee85 100644 --- a/app/helpers/commits_helper.rb +++ b/app/helpers/commits_helper.rb @@ -215,7 +215,7 @@ module CommitsHelper path = project_blob_path(project, tree_join(commit_sha, diff_new_path)) title = replaced ? _('View replaced file @ ') : _('View file @ ') - link_to(path, class: 'btn gl-button btn-default') do + link_to(path, class: 'btn gl-button btn-default gl-ml-3') do raw(title) + content_tag(:span, truncate_sha(commit_sha), class: 'commit-sha') end end diff --git a/app/helpers/compare_helper.rb b/app/helpers/compare_helper.rb index b07baf59114..f9d62747308 100644 --- a/app/helpers/compare_helper.rb +++ b/app/helpers/compare_helper.rb @@ -38,10 +38,8 @@ module CompareHelper project_merge_request_path: merge_request.present? ? project_merge_request_path(project, merge_request) : '', create_mr_path: create_mr_button? ? create_mr_path : '' }.tap do |data| - if Feature.enabled?(:compare_repo_dropdown, project, default_enabled: :yaml) - data[:project_to] = { id: project.id, name: project.full_path }.to_json - data[:projects_from] = target_projects(project).map { |project| { id: project.id, name: project.full_path } }.to_json - end + data[:project_to] = { id: project.id, name: project.full_path }.to_json + data[:projects_from] = target_projects(project).map { |project| { id: project.id, name: project.full_path } }.to_json end end end diff --git a/app/helpers/dashboard_helper.rb b/app/helpers/dashboard_helper.rb index 95bbf2eff41..f0e1f252917 100644 --- a/app/helpers/dashboard_helper.rb +++ b/app/helpers/dashboard_helper.rb @@ -23,10 +23,6 @@ module DashboardHelper dashboard_nav_links.include?(link) end - def any_dashboard_nav_link?(links) - links.any? { |link| dashboard_nav_link?(link) } - end - def has_start_trial? false end diff --git a/app/helpers/diff_helper.rb b/app/helpers/diff_helper.rb index 3aa54e3afe9..40d7eab584c 100644 --- a/app/helpers/diff_helper.rb +++ b/app/helpers/diff_helper.rb @@ -273,14 +273,14 @@ module DiffHelper Gitlab::CodeNavigationPath.new(merge_request.project, merge_request.diff_head_sha) end - def conflicts + def conflicts(allow_tree_conflicts: false) return unless options[:merge_ref_head_diff] - conflicts_service = MergeRequests::Conflicts::ListService.new(merge_request) # rubocop:disable CodeReuse/ServiceClass + conflicts_service = MergeRequests::Conflicts::ListService.new(merge_request, allow_tree_conflicts: allow_tree_conflicts) # rubocop:disable CodeReuse/ServiceClass - return unless conflicts_service.can_be_resolved_in_ui? + return unless allow_tree_conflicts || conflicts_service.can_be_resolved_in_ui? - conflicts_service.conflicts.files.index_by(&:our_path) + conflicts_service.conflicts.files.index_by(&:path) end def log_overflow_limits(diff_files:, collection_overflow:) diff --git a/app/helpers/emails_helper.rb b/app/helpers/emails_helper.rb index 0b1bdb68e50..b804efb9561 100644 --- a/app/helpers/emails_helper.rb +++ b/app/helpers/emails_helper.rb @@ -7,21 +7,9 @@ module EmailsHelper # https://developers.google.com/gmail/markup/reference/go-to-action def email_action(url) name = action_title(url) - if name - data = { - "@context" => "http://schema.org", - "@type" => "EmailMessage", - "action" => { - "@type" => "ViewAction", - "name" => name, - "url" => url - } - } - - content_tag :script, type: 'application/ld+json' do - data.to_json.html_safe - end - end + return unless name + + gmail_goto_action(name, url) end def action_title(url) @@ -36,6 +24,22 @@ module EmailsHelper nil end + def gmail_goto_action(name, url) + data = { + "@context" => "http://schema.org", + "@type" => "EmailMessage", + "action" => { + "@type" => "ViewAction", + "name" => name, + "url" => url + } + } + + content_tag :script, type: 'application/ld+json' do + data.to_json.html_safe + end + end + def sanitize_name(name) if name =~ URI::DEFAULT_PARSER.regexp[:URI_REF] name.tr('.', '_') diff --git a/app/helpers/environment_helper.rb b/app/helpers/environment_helper.rb index 491d2731e91..3f23f73eed7 100644 --- a/app/helpers/environment_helper.rb +++ b/app/helpers/environment_helper.rb @@ -65,4 +65,31 @@ module EnvironmentHelper content_tag(:span, text, class: klass) end end + + def environments_detail_data(user, project, environment) + { + name: environment.name, + id: environment.id, + external_url: environment.external_url, + can_update_environment: can?(current_user, :update_environment, environment), + can_destroy_environment: can_destroy_environment?(environment), + can_read_environment: can?(current_user, :read_environment, environment), + can_stop_environment: can?(current_user, :stop_environment, environment), + can_admin_environment: can?(current_user, :admin_environment, project), + environment_metrics_path: environment_metrics_path(environment), + environments_fetch_path: project_environments_path(project, format: :json), + environment_edit_path: edit_project_environment_path(project, environment), + environment_stop_path: stop_project_environment_path(project, environment), + environment_delete_path: environment_delete_path(environment), + environment_cancel_auto_stop_path: cancel_auto_stop_project_environment_path(project, environment), + environment_terminal_path: terminal_project_environment_path(project, environment), + has_terminals: environment.has_terminals?, + is_environment_available: environment.available?, + auto_stop_at: environment.auto_stop_at + } + end + + def environments_detail_data_json(user, project, environment) + environments_detail_data(user, project, environment).to_json + end end diff --git a/app/helpers/environments_helper.rb b/app/helpers/environments_helper.rb index 62060200698..b2842664879 100644 --- a/app/helpers/environments_helper.rb +++ b/app/helpers/environments_helper.rb @@ -45,6 +45,14 @@ module EnvironmentsHelper can?(current_user, :destroy_environment, environment) end + def environment_data(environment) + Gitlab::Json.generate({ + id: environment.id, + name: environment.name, + external_url: environment.external_url + }) + end + private def project_metrics_data(project) diff --git a/app/helpers/groups/group_members_helper.rb b/app/helpers/groups/group_members_helper.rb index c4d920dc317..07ab246b089 100644 --- a/app/helpers/groups/group_members_helper.rb +++ b/app/helpers/groups/group_members_helper.rb @@ -13,7 +13,7 @@ module Groups::GroupMembersHelper render 'shared/members/invite_member', submit_url: group_group_members_path(group), access_levels: group.access_level_roles, default_access_level: default_access_level end - def group_members_app_data_json(group, members:, invited:, access_requests:) + def group_members_app_data(group, members:, invited:, access_requests:) { user: group_members_list_data(group, members, { param_name: :page, params: { invited_members_page: nil, search_invited: nil } }), group: group_group_links_list_data(group), @@ -21,7 +21,7 @@ module Groups::GroupMembersHelper access_request: group_members_list_data(group, access_requests.nil? ? [] : access_requests), source_id: group.id, can_manage_members: can?(current_user, :admin_group_member, group) - }.to_json + } end private diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb index 400ad721b06..0e4aeaae20d 100644 --- a/app/helpers/groups_helper.rb +++ b/app/helpers/groups_helper.rb @@ -1,52 +1,6 @@ # frozen_string_literal: true module GroupsHelper - def group_overview_nav_link_paths - %w[ - groups#activity - groups#subgroups - labels#index - group_members#index - ] - end - - def group_settings_nav_link_paths - %w[ - groups#projects - groups#edit - badges#index - repository#show - ci_cd#show - integrations#index - integrations#edit - ldap_group_links#index - hooks#index - pipeline_quota#index - applications#index - applications#show - applications#edit - packages_and_registries#show - groups/runners#show - groups/runners#edit - ] - end - - def group_packages_nav_link_paths - %w[ - groups/packages#index - groups/container_registries#index - ] - end - - def group_information_title(group) - group.subgroup? ? _('Subgroup information') : _('Group information') - end - - def group_container_registry_nav? - Gitlab.config.registry.enabled && - can?(current_user, :read_container_image, @group) - end - def group_sidebar_links @group_sidebar_links ||= get_group_sidebar_links end @@ -75,6 +29,10 @@ module GroupsHelper can?(current_user, :set_emails_disabled, group) && !group.parent&.emails_disabled? end + def can_admin_group_member?(group) + Ability.allowed?(current_user, :admin_group_member, group) + end + def group_issues_count(state:) IssuesFinder .new(current_user, group_id: @group.id, state: state, non_archived: true, include_subgroups: true) @@ -89,18 +47,13 @@ module GroupsHelper .count end - def cached_issuables_count(group, type: nil) - count_service = issuables_count_service_class(type) - return unless count_service.present? - - issuables_count = count_service.new(group, current_user).count - format_issuables_count(count_service, issuables_count) - end - - def group_dependency_proxy_url(group) + def group_dependency_proxy_image_prefix(group) # The namespace path can include uppercase letters, which # Docker doesn't allow. The proxy expects it to be downcased. - "#{group_url(group).downcase}#{DependencyProxy::URL_SUFFIX}" + url = "#{group_url(group).downcase}#{DependencyProxy::URL_SUFFIX}" + + # Docker images do not include the protocol + url.partition('//').last end def group_icon_url(group, options = {}) @@ -164,7 +117,7 @@ module GroupsHelper end def remove_group_message(group) - _("You are going to remove %{group_name}, this will also delete all of its subgroups and projects. Removed groups CANNOT be restored! Are you ABSOLUTELY sure?") % + _("You are going to remove %{group_name}. This will also delete all of its subgroups and projects. Removed groups CANNOT be restored! Are you ABSOLUTELY sure?") % { group_name: group.name } end @@ -200,19 +153,6 @@ module GroupsHelper groups.to_json end - def group_packages_nav? - group_packages_list_nav? || - group_container_registry_nav? - end - - def group_dependency_proxy_nav? - @group.dependency_proxy_feature_available? - end - - def group_packages_list_nav? - @group.packages_feature_enabled? - end - def show_invite_banner?(group) can?(current_user, :admin_group, group) && !just_created? && @@ -250,6 +190,12 @@ module GroupsHelper can?(current_user, "read_group_#{resource}".to_sym, @group) end + # TODO Proper policies, such as `read_group_runners, should be implemented per + # See https://gitlab.com/gitlab-org/gitlab/-/issues/334802 + if can?(current_user, :admin_group, @group) && Feature.enabled?(:runner_list_group_view_vue_ui, @group, default_enabled: :yaml) + links << :runners + end + if can?(current_user, :read_cluster, @group) links << :kubernetes end @@ -322,24 +268,8 @@ module GroupsHelper s_("GroupSettings|This setting is applied on %{ancestor_group} and has been overridden on this subgroup.").html_safe % { ancestor_group: ancestor_group(group) } end - def issuables_count_service_class(type) - if type == :issues - Groups::OpenIssuesCountService - elsif type == :merge_requests - Groups::MergeRequestsCountService - end - end - - def format_issuables_count(count_service, count) - if count > count_service::CACHED_COUNT_THRESHOLD - ActiveSupport::NumberHelper - .number_to_human( - count, - units: { thousand: 'k', million: 'm' }, precision: 1, significant: false, format: '%n%u' - ) - else - number_with_delimiter(count) - end + def group_url_error_message + s_('GroupSettings|Please choose a group URL with no special characters or spaces.') end end diff --git a/app/helpers/ide_helper.rb b/app/helpers/ide_helper.rb index b92e418006b..41c7abbbabd 100644 --- a/app/helpers/ide_helper.rb +++ b/app/helpers/ide_helper.rb @@ -8,7 +8,7 @@ module IdeHelper 'committed-state-svg-path' => image_path('illustrations/multi-editor_all_changes_committed_empty.svg'), 'pipelines-empty-state-svg-path': image_path('illustrations/pipelines_empty.svg'), 'promotion-svg-path': image_path('illustrations/web-ide_promotion.svg'), - 'ci-help-page-path' => help_page_path('ci/quick_start/README'), + 'ci-help-page-path' => help_page_path('ci/quick_start/index'), 'web-ide-help-page-path' => help_page_path('user/project/web_ide/index.md'), 'clientside-preview-enabled': Gitlab::CurrentSettings.web_ide_clientside_preview_enabled?.to_s, 'render-whitespace-in-code': current_user.render_whitespace_in_code.to_s, diff --git a/app/helpers/integrations_helper.rb b/app/helpers/integrations_helper.rb index ab305d822e8..f15566a551a 100644 --- a/app/helpers/integrations_helper.rb +++ b/app/helpers/integrations_helper.rb @@ -47,6 +47,10 @@ module IntegrationsHelper end end + def scoped_overrides_integration_path(integration, options = {}) + overrides_admin_application_settings_integration_path(integration, options) + end + def scoped_test_integration_path(integration) if @project.present? test_project_service_path(@project, integration) @@ -97,6 +101,12 @@ module IntegrationsHelper form_data end + def integration_overrides_data(integration) + { + overrides_path: scoped_overrides_integration_path(integration, format: :json) + } + end + def integration_list_data(integrations) { integrations: integrations.map { |i| serialize_integration(i) }.to_json @@ -115,6 +125,15 @@ module IntegrationsHelper !Gitlab.com? end + def integration_tabs(integration:) + [ + { key: 'edit', text: _('Settings'), href: scoped_edit_integration_path(integration) }, + ( + { key: 'overrides', text: s_('Integrations|Projects using custom settings'), href: scoped_overrides_integration_path(integration) } if integration.instance_level? + ) + ].compact + end + def jira_issue_breadcrumb_link(issue_reference) link_to '', { class: 'gl-display-flex gl-align-items-center gl-white-space-nowrap' } do icon = image_tag image_path('illustrations/logos/jira.svg'), width: 15, height: 15, class: 'gl-mr-2' diff --git a/app/helpers/invite_members_helper.rb b/app/helpers/invite_members_helper.rb index 3c290701a5f..5134b484249 100644 --- a/app/helpers/invite_members_helper.rb +++ b/app/helpers/invite_members_helper.rb @@ -4,21 +4,17 @@ module InviteMembersHelper include Gitlab::Utils::StrongMemoize def can_invite_members_for_project?(project) - Feature.enabled?(:invite_members_group_modal, project.group) && can_manage_project_members?(project) + # do not use the can_admin_project_member? helper here due to structure of the view and how membership_locked? + # is leveraged for inviting groups + Feature.enabled?(:invite_members_group_modal, project.group) && can?(current_user, :admin_project_member, project) end def can_invite_group_for_project?(project) - Feature.enabled?(:invite_members_group_modal, project.group) && can_manage_project_members?(project) && project.allowed_to_share_with_group? - end - - def directly_invite_members? - strong_memoize(:directly_invite_members) do - can_import_members? - end - end - - def invite_group_members?(group) - experiment_enabled?(:invite_members_empty_group_version_a) && Ability.allowed?(current_user, :admin_group_member, group) + # do not use the can_admin_project_member? helper here due to structure of the view and how membership_locked? + # is leveraged for inviting groups + Feature.enabled?(:invite_members_group_modal, project.group) && + can?(current_user, :admin_project_member, project) && + project.allowed_to_share_with_group? end def invite_accepted_notice(member) @@ -39,4 +35,48 @@ module InviteMembersHelper {} end end + + def common_invite_modal_dataset(source) + dataset = { + id: source.id, + name: source.name, + default_access_level: Gitlab::Access::GUEST + } + + experiment(:member_areas_of_focus, user: current_user) do |e| + e.publish_to_database + + e.control { dataset.merge!(areas_of_focus_options: [], no_selection_areas_of_focus: []) } + e.candidate { dataset.merge!(areas_of_focus_options: member_areas_of_focus_options.to_json, no_selection_areas_of_focus: ['no_selection']) } + end + + dataset + end + + private + + def member_areas_of_focus_options + [ + { + value: 'Contribute to the codebase', text: s_('InviteMembersModal|Contribute to the codebase') + }, + { + value: 'Collaborate on open issues and merge requests', text: s_('InviteMembersModal|Collaborate on open issues and merge requests') + }, + { + value: 'Configure CI/CD', text: s_('InviteMembersModal|Configure CI/CD') + }, + { + value: 'Configure security features', text: s_('InviteMembersModal|Configure security features') + }, + { + value: 'Other', text: s_('InviteMembersModal|Other') + } + ] + end + + # Overridden in EE + def users_filter_data(group) + {} + end end diff --git a/app/helpers/issuables_description_templates_helper.rb b/app/helpers/issuables_description_templates_helper.rb index 6cafde65c5c..a5b9a6eee80 100644 --- a/app/helpers/issuables_description_templates_helper.rb +++ b/app/helpers/issuables_description_templates_helper.rb @@ -32,13 +32,14 @@ module IssuablesDescriptionTemplatesHelper @template_types[project.id][issuable_type] ||= TemplateFinder.all_template_names(project, issuable_type.pluralize) end - def issuable_templates_names(issuable) + # Overriden on EE::IssuablesDescriptionTemplatesHelper to include inherited templates names + def issuable_templates_names(issuable, include_inherited_templates = false) all_templates = issuable_templates(ref_project, issuable.to_ability_name) all_templates.values.flatten.map { |tpl| tpl[:name] if tpl[:project_id] == ref_project.id }.compact.uniq end def selected_template(issuable) - params[:issuable_template] if issuable_templates_names(issuable).any? { |tmpl_name| tmpl_name == params[:issuable_template] } + params[:issuable_template] if issuable_templates_names(issuable, true).any? { |tmpl_name| tmpl_name == params[:issuable_template] } end def template_names_path(parent, issuable) @@ -47,3 +48,5 @@ module IssuablesDescriptionTemplatesHelper project_template_names_path(parent, template_type: issuable.to_ability_name) end end + +IssuablesDescriptionTemplatesHelper.prepend_mod diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb index 5bedfc61d46..bbafdac9a7f 100644 --- a/app/helpers/issues_helper.rb +++ b/app/helpers/issues_helper.rb @@ -48,10 +48,22 @@ module IssuesHelper end end + def work_item_type_icon(issue_type) + if WorkItem::Type.base_types.include?(issue_type) + "issue-type-#{issue_type.to_s.dasherize}" + else + 'issue-type-issue' + end + end + def confidential_icon(issue) sprite_icon('eye-slash', css_class: 'gl-vertical-align-text-bottom') if issue.confidential? end + def hidden_issue_icon(issue) + sprite_icon('spam', css_class: 'gl-vertical-align-text-bottom') if issue.hidden? + end + def award_user_list(awards, current_user, limit: 10) names = awards.map do |award| award.user == current_user ? 'You' : award.user.name @@ -195,7 +207,7 @@ module IssuesHelper initial_email: project.new_issuable_address(current_user, 'issue'), is_signed_in: current_user.present?.to_s, issues_path: project_issues_path(project), - jira_integration_path: help_page_url('integration/jira/', anchor: 'view-jira-issues'), + jira_integration_path: help_page_url('integration/jira/issues', anchor: 'view-jira-issues'), markdown_help_path: help_page_path('user/markdown'), max_attachment_size: number_to_human_size(Gitlab::CurrentSettings.max_attachment_size.megabytes), new_issue_path: new_project_issue_path(project, issue: { milestone_id: finder.milestones.first.try(:id) }), diff --git a/app/helpers/markup_helper.rb b/app/helpers/markup_helper.rb index 7525481047e..f185d6cd002 100644 --- a/app/helpers/markup_helper.rb +++ b/app/helpers/markup_helper.rb @@ -250,7 +250,7 @@ module MarkupHelper data = options[:data].merge({ container: 'body' }) content_tag :button, type: 'button', - class: 'toolbar-btn js-md has-tooltip', + class: 'gl-button btn btn-default-tertiary btn-icon js-md has-tooltip', data: data, title: options[:title], aria: { label: options[:title] } do diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb index 81059834136..d5d692f2d6e 100644 --- a/app/helpers/merge_requests_helper.rb +++ b/app/helpers/merge_requests_helper.rb @@ -186,7 +186,10 @@ module MergeRequestsHelper show_suggest_popover: show_suggest_popover?.to_s, show_whitespace_default: @show_whitespace_default.to_s, file_by_file_default: @file_by_file_default.to_s, - default_suggestion_commit_message: default_suggestion_commit_message + default_suggestion_commit_message: default_suggestion_commit_message, + source_project_default_url: @merge_request.source_project && default_url_to_repo(@merge_request.source_project), + source_project_full_path: @merge_request.source_project&.full_path, + is_forked: @project.forked?.to_s } end diff --git a/app/helpers/nav/new_dropdown_helper.rb b/app/helpers/nav/new_dropdown_helper.rb index ff8839d68fd..0384f82f1f1 100644 --- a/app/helpers/nav/new_dropdown_helper.rb +++ b/app/helpers/nav/new_dropdown_helper.rb @@ -101,7 +101,7 @@ module Nav ) end - if Gitlab::Experimentation.active?(:invite_members_new_dropdown) && can_import_members? + if Gitlab::Experimentation.active?(:invite_members_new_dropdown) && can_admin_project_member?(project) menu_items.push( invite_members_menu_item( href: project_project_members_path(project) diff --git a/app/helpers/nav_helper.rb b/app/helpers/nav_helper.rb index 6c57a31f3db..9a6630ec3cb 100644 --- a/app/helpers/nav_helper.rb +++ b/app/helpers/nav_helper.rb @@ -67,15 +67,6 @@ module NavHelper %w(dev_ops_report usage_trends) end - def group_issues_sub_menu_items - %w[ - groups#issues - milestones#index - boards#index - boards#show - ] - end - private def get_header_links diff --git a/app/helpers/packages_helper.rb b/app/helpers/packages_helper.rb index 50984415aa5..1a466c9d170 100644 --- a/app/helpers/packages_helper.rb +++ b/app/helpers/packages_helper.rb @@ -64,9 +64,10 @@ module PackagesHelper project.container_repositories.exists? end - def package_details_data(project, package = nil) + def package_details_data(project, package, use_presenter = false) { - package: package ? package_from_presenter(package) : nil, + package: use_presenter ? package_from_presenter(package) : nil, + package_id: package.id, can_delete: can?(current_user, :destroy_package, project).to_s, svg_path: image_path('illustrations/no-packages.svg'), npm_path: package_registry_instance_url(:npm), diff --git a/app/helpers/projects/project_members_helper.rb b/app/helpers/projects/project_members_helper.rb index 0871d5638b8..514737b1417 100644 --- a/app/helpers/projects/project_members_helper.rb +++ b/app/helpers/projects/project_members_helper.rb @@ -1,32 +1,6 @@ # frozen_string_literal: true module Projects::ProjectMembersHelper - def can_manage_project_members?(project) - can?(current_user, :admin_project_member, project) - end - - def show_groups?(group_links) - group_links.exists? || groups_tab_active? - end - - def show_invited_members?(project, invited_members) - can_manage_project_members?(project) && invited_members.exists? - end - - def show_access_requests?(project, requesters) - can_manage_project_members?(project) && requesters.exists? - end - - def groups_tab_active? - params[:search_groups].present? - end - - def current_user_is_group_owner?(project) - return false if project.group.nil? - - project.group.has_owner?(current_user) - end - def project_members_app_data_json(project, members:, group_links:, invited:, access_requests:) { user: project_members_list_data(project, members, { param_name: :page, params: { search_groups: nil } }), @@ -34,7 +8,7 @@ module Projects::ProjectMembersHelper invite: project_members_list_data(project, invited.nil? ? [] : invited), access_request: project_members_list_data(project, access_requests.nil? ? [] : access_requests), source_id: project.id, - can_manage_members: can_manage_project_members?(project) + can_manage_members: Ability.allowed?(current_user, :admin_project_member, project) }.to_json end diff --git a/app/helpers/projects/terraform_helper.rb b/app/helpers/projects/terraform_helper.rb index 621d97ffb69..fb35224fad3 100644 --- a/app/helpers/projects/terraform_helper.rb +++ b/app/helpers/projects/terraform_helper.rb @@ -5,7 +5,10 @@ module Projects::TerraformHelper { empty_state_image: image_path('illustrations/empty-state/empty-serverless-lg.svg'), project_path: project.full_path, - terraform_admin: current_user&.can?(:admin_terraform_state, project) + terraform_admin: current_user&.can?(:admin_terraform_state, project), + access_tokens_path: profile_personal_access_tokens_path, + username: current_user&.username, + terraform_api_url: "#{Settings.gitlab.url}/api/v4/projects/#{project.id}/terraform/state" } end end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 752e91df9c4..f30223f6f1e 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -291,8 +291,8 @@ module ProjectsHelper ) % { default_label: default_label } end - def can_import_members? - Ability.allowed?(current_user, :admin_project_member, @project) + def can_admin_project_member?(project) + Ability.allowed?(current_user, :admin_project_member, project) && !membership_locked? end def project_can_be_shared? @@ -354,6 +354,29 @@ module ProjectsHelper project.repository_languages.with_programming_language('HCL').exists? && project.terraform_states.empty? end + def project_permissions_panel_data(project) + { + packagesAvailable: ::Gitlab.config.packages.enabled, + packagesHelpPath: help_page_path('user/packages/index'), + currentSettings: project_permissions_settings(project), + canDisableEmails: can_disable_emails?(project, current_user), + canChangeVisibilityLevel: can_change_visibility_level?(project, current_user), + allowedVisibilityOptions: project_allowed_visibility_levels(project), + visibilityHelpPath: help_page_path('public_access/public_access'), + registryAvailable: Gitlab.config.registry.enabled, + registryHelpPath: help_page_path('user/packages/container_registry/index'), + lfsAvailable: Gitlab.config.lfs.enabled, + lfsHelpPath: help_page_path('topics/git/lfs/index'), + lfsObjectsExist: project.lfs_objects.exists?, + lfsObjectsRemovalHelpPath: help_page_path('topics/git/lfs/index', anchor: 'removing-objects-from-lfs'), + pagesAvailable: Gitlab.config.pages.enabled, + pagesAccessControlEnabled: Gitlab.config.pages.access_control, + pagesAccessControlForced: ::Gitlab::Pages.access_control_is_forced?, + pagesHelpPath: help_page_path('user/project/pages/introduction', anchor: 'gitlab-pages-access-control'), + issuesHelpPath: help_page_path('user/project/issues/index') + } + end + private def tab_ability_map @@ -491,7 +514,6 @@ module ProjectsHelper def project_permissions_settings(project) feature = project.project_feature - { packagesEnabled: !!project.packages_enabled, visibilityLevel: project.visibility_level, @@ -511,38 +533,11 @@ module ProjectsHelper metricsDashboardAccessLevel: feature.metrics_dashboard_access_level, operationsAccessLevel: feature.operations_access_level, showDefaultAwardEmojis: project.show_default_award_emojis?, - allowEditingCommitMessages: project.allow_editing_commit_messages?, - securityAndComplianceAccessLevel: project.security_and_compliance_access_level + securityAndComplianceAccessLevel: project.security_and_compliance_access_level, + containerRegistryAccessLevel: feature.container_registry_access_level } end - def project_permissions_panel_data(project) - { - packagesAvailable: ::Gitlab.config.packages.enabled, - packagesHelpPath: help_page_path('user/packages/index'), - currentSettings: project_permissions_settings(project), - canDisableEmails: can_disable_emails?(project, current_user), - canChangeVisibilityLevel: can_change_visibility_level?(project, current_user), - allowedVisibilityOptions: project_allowed_visibility_levels(project), - visibilityHelpPath: help_page_path('public_access/public_access'), - registryAvailable: Gitlab.config.registry.enabled, - registryHelpPath: help_page_path('user/packages/container_registry/index'), - lfsAvailable: Gitlab.config.lfs.enabled, - lfsHelpPath: help_page_path('topics/git/lfs/index'), - lfsObjectsExist: project.lfs_objects.exists?, - lfsObjectsRemovalHelpPath: help_page_path('topics/git/lfs/index', anchor: 'removing-objects-from-lfs'), - pagesAvailable: Gitlab.config.pages.enabled, - pagesAccessControlEnabled: Gitlab.config.pages.access_control, - pagesAccessControlForced: ::Gitlab::Pages.access_control_is_forced?, - pagesHelpPath: help_page_path('user/project/pages/introduction', anchor: 'gitlab-pages-access-control'), - issuesHelpPath: help_page_path('user/project/issues/index') - } - end - - def project_permissions_panel_data_json(project) - project_permissions_panel_data(project).to_json.html_safe - end - def project_allowed_visibility_levels(project) Gitlab::VisibilityLevel.values.select do |level| project.visibility_level_allowed?(level) && !restricted_levels.include?(level) diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb index ec8ed3d6e7f..409a3e65fe3 100644 --- a/app/helpers/search_helper.rb +++ b/app/helpers/search_helper.rb @@ -150,7 +150,7 @@ module SearchHelper } ] - if search_service.scope == 'issues' && Feature.enabled?(:search_sort_issues_by_popularity) + if search_service.scope == 'issues' options << { title: _('Popularity'), sortable: true, @@ -189,7 +189,7 @@ module SearchHelper { category: "Help", label: _("Markdown Help"), url: help_page_path("user/markdown") }, { category: "Help", label: _("Permissions Help"), url: help_page_path("user/permissions") }, { category: "Help", label: _("Public Access Help"), url: help_page_path("public_access/public_access") }, - { category: "Help", label: _("Rake Tasks Help"), url: help_page_path("raketasks/README") }, + { category: "Help", label: _("Rake Tasks Help"), url: help_page_path("raketasks/index") }, { category: "Help", label: _("SSH Keys Help"), url: help_page_path("ssh/index") }, { category: "Help", label: _("System Hooks Help"), url: help_page_path("system_hooks/system_hooks") }, { category: "Help", label: _("Webhooks Help"), url: help_page_path("user/project/integrations/webhooks") } diff --git a/app/helpers/snippets_helper.rb b/app/helpers/snippets_helper.rb index 84eb0405c01..e9ef9146529 100644 --- a/app/helpers/snippets_helper.rb +++ b/app/helpers/snippets_helper.rb @@ -39,6 +39,12 @@ module SnippetsHelper end end + def snippet_report_abuse_path(snippet) + return unless snippet.submittable_as_spam_by?(current_user) + + mark_as_spam_snippet_path(snippet) + end + def embedded_raw_snippet_button(snippet, blob) return if blob.empty? || blob.binary? || blob.stored_externally? diff --git a/app/helpers/sorting_helper.rb b/app/helpers/sorting_helper.rb index da32dfb0b9b..7fa85d143f7 100644 --- a/app/helpers/sorting_helper.rb +++ b/app/helpers/sorting_helper.rb @@ -3,6 +3,7 @@ module SortingHelper include SortingTitlesValuesHelper + # rubocop: disable Metrics/AbcSize def sort_options_hash { sort_value_created_date => sort_title_created_date, @@ -29,6 +30,9 @@ module SortingHelper sort_value_merged_date => sort_title_merged_date, sort_value_merged_recently => sort_title_merged_recently, sort_value_merged_earlier => sort_title_merged_earlier, + sort_value_closed_date => sort_title_closed_date, + sort_value_closed_recently => sort_title_closed_recently, + sort_value_closed_earlier => sort_title_closed_earlier, sort_value_upvotes => sort_title_upvotes, sort_value_contacted_date => sort_title_contacted_date, sort_value_relative_position => sort_title_relative_position, @@ -36,6 +40,7 @@ module SortingHelper sort_value_expire_date => sort_title_expire_date } end + # rubocop: enable Metrics/AbcSize def projects_sort_options_hash use_old_sorting = Feature.disabled?(:project_list_filter_bar) || current_controller?('admin/projects') @@ -182,6 +187,7 @@ module SortingHelper sort_value_milestone_later => sort_value_milestone, sort_value_due_date_later => sort_value_due_date, sort_value_merged_recently => sort_value_merged_date, + sort_value_closed_recently => sort_value_closed_date, sort_value_least_popular => sort_value_popularity } end @@ -196,6 +202,8 @@ module SortingHelper sort_value_due_date_soon => sort_value_due_date_later, sort_value_merged_date => sort_value_merged_recently, sort_value_merged_earlier => sort_value_merged_recently, + sort_value_closed_date => sort_value_closed_recently, + sort_value_closed_earlier => sort_value_closed_recently, sort_value_popularity => sort_value_least_popular, sort_value_most_popular => sort_value_least_popular }.merge(issuable_sort_option_overrides) @@ -216,7 +224,7 @@ module SortingHelper def sort_direction_icon(sort_value) case sort_value - when sort_value_milestone, sort_value_due_date, sort_value_merged_date, /_asc\z/ + when sort_value_milestone, sort_value_due_date, sort_value_merged_date, sort_value_closed_date, /_asc\z/ 'sort-lowest' else 'sort-highest' diff --git a/app/helpers/sorting_titles_values_helper.rb b/app/helpers/sorting_titles_values_helper.rb index 9b839f4e9bc..f4117d690f3 100644 --- a/app/helpers/sorting_titles_values_helper.rb +++ b/app/helpers/sorting_titles_values_helper.rb @@ -38,6 +38,18 @@ module SortingTitlesValuesHelper s_('SortOptions|Merged earlier') end + def sort_title_closed_date + s_('SortOptions|Closed date') + end + + def sort_title_closed_recently + s_('SortOptions|Closed recently') + end + + def sort_title_closed_earlier + s_('SortOptions|Closed earlier') + end + def sort_title_largest_group s_('SortOptions|Largest group') end @@ -199,6 +211,18 @@ module SortingTitlesValuesHelper 'merged_at_asc' end + def sort_value_closed_date + 'closed_at' + end + + def sort_value_closed_recently + 'closed_at_desc' + end + + def sort_value_closed_earlier + 'closed_at_asc' + end + def sort_value_largest_group 'storage_size_desc' end diff --git a/app/helpers/time_zone_helper.rb b/app/helpers/time_zone_helper.rb index fe045182c96..f92e32ff9b6 100644 --- a/app/helpers/time_zone_helper.rb +++ b/app/helpers/time_zone_helper.rb @@ -31,4 +31,9 @@ module TimeZoneHelper }.slice(*attrs) end end + + def local_time(timezone) + time_zone_instance = ActiveSupport::TimeZone.new(timezone) || Time.zone + time_zone_instance.now.strftime("%-l:%M %p") + end end diff --git a/app/helpers/tree_helper.rb b/app/helpers/tree_helper.rb index 54c03d3d966..d1f33f99ad0 100644 --- a/app/helpers/tree_helper.rb +++ b/app/helpers/tree_helper.rb @@ -178,7 +178,7 @@ module TreeHelper def web_ide_button_data(options = {}) { project_path: project_to_use.full_path, - ref: ActionDispatch::Journey::Router::Utils.escape_path(@ref), + ref: @ref, is_fork: fork?, needs_to_fork: needs_to_fork?, diff --git a/app/helpers/user_callouts_helper.rb b/app/helpers/user_callouts_helper.rb index 4e6af298fcd..f5a74a3f57d 100644 --- a/app/helpers/user_callouts_helper.rb +++ b/app/helpers/user_callouts_helper.rb @@ -4,7 +4,6 @@ module UserCalloutsHelper GKE_CLUSTER_INTEGRATION = 'gke_cluster_integration' GCP_SIGNUP_OFFER = 'gcp_signup_offer' SUGGEST_POPOVER_DISMISSED = 'suggest_popover_dismissed' - SERVICE_TEMPLATES_DEPRECATED_CALLOUT = 'service_templates_deprecated_callout' TABS_POSITION_HIGHLIGHT = 'tabs_position_highlight' CUSTOMIZE_HOMEPAGE = 'customize_homepage' FEATURE_FLAGS_NEW_VERSION = 'feature_flags_new_version' @@ -35,13 +34,6 @@ module UserCalloutsHelper !user_dismissed?(SUGGEST_POPOVER_DISMISSED) end - def show_service_templates_deprecated_callout? - !Gitlab.com? && - current_user&.admin? && - Integration.for_template.active.exists? && - !user_dismissed?(SERVICE_TEMPLATES_DEPRECATED_CALLOUT) - end - def show_customize_homepage_banner? current_user.default_dashboard? && !user_dismissed?(CUSTOMIZE_HOMEPAGE) end @@ -61,6 +53,9 @@ module UserCalloutsHelper !user_dismissed?(REGISTRATION_ENABLED_CALLOUT) end + def dismiss_account_recovery_regular_check + end + private def user_dismissed?(feature_name, ignore_dismissal_earlier_than = nil) @@ -70,4 +65,4 @@ module UserCalloutsHelper end end -UserCalloutsHelper.prepend_mod_with('UserCalloutsHelper') +UserCalloutsHelper.prepend_mod diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb index 93a0166f43e..c64c2ab35fb 100644 --- a/app/helpers/users_helper.rb +++ b/app/helpers/users_helper.rb @@ -184,7 +184,7 @@ module UsersHelper activate: activate_admin_user_path(:id), unlock: unlock_admin_user_path(:id), delete: admin_user_path(:id), - delete_with_contributions: admin_user_path(:id), + delete_with_contributions: admin_user_path(:id, hard_delete: true), admin_user: admin_user_path(:id), ban: ban_admin_user_path(:id), unban: unban_admin_user_path(:id) -- cgit v1.2.3