diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-07-20 15:40:28 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-07-20 15:40:28 +0000 |
commit | b595cb0c1dec83de5bdee18284abe86614bed33b (patch) | |
tree | 8c3d4540f193c5ff98019352f554e921b3a41a72 /app/helpers | |
parent | 2f9104a328fc8a4bddeaa4627b595166d24671d0 (diff) | |
download | gitlab-ce-b595cb0c1dec83de5bdee18284abe86614bed33b.tar.gz |
Add latest changes from gitlab-org/gitlab@15-2-stable-eev15.2.0-rc42
Diffstat (limited to 'app/helpers')
28 files changed, 251 insertions, 81 deletions
diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb index cd31d2c75ab..321a6e9395e 100644 --- a/app/helpers/application_settings_helper.rb +++ b/app/helpers/application_settings_helper.rb @@ -238,6 +238,8 @@ module ApplicationSettingsHelper :email_author_in_body, :enabled_git_access_protocol, :enforce_terms, + :error_tracking_enabled, + :error_tracking_api_url, :external_pipeline_validation_service_timeout, :external_pipeline_validation_service_token, :external_pipeline_validation_service_url, @@ -402,6 +404,7 @@ module ApplicationSettingsHelper :wiki_page_max_content_bytes, :container_registry_delete_tags_service_timeout, :rate_limiting_response_text, + :package_registry_cleanup_policies_worker_capacity, :container_registry_expiration_policies_worker_capacity, :container_registry_cleanup_tags_service_max_list_size, :container_registry_import_max_tags_count, diff --git a/app/helpers/ci/pipeline_editor_helper.rb b/app/helpers/ci/pipeline_editor_helper.rb index bb3f7b5aa79..d044a93213a 100644 --- a/app/helpers/ci/pipeline_editor_helper.rb +++ b/app/helpers/ci/pipeline_editor_helper.rb @@ -18,6 +18,7 @@ module Ci "ci-config-path": project.ci_config_path_or_default, "ci-examples-help-page-path" => help_page_path('ci/examples/index'), "ci-help-page-path" => help_page_path('ci/index'), + "ci-lint-path" => project_ci_lint_path(project), "default-branch" => project.default_branch_or_main, "empty-state-illustration-path" => image_path('illustrations/empty-state/empty-dag-md.svg'), "initial-branch-name" => initial_branch, @@ -32,6 +33,7 @@ module Ci "project-full-path" => project.full_path, "project-namespace" => project.namespace.full_path, "runner-help-page-path" => help_page_path('ci/runners/index'), + "simulate-pipeline-help-page-path" => help_page_path('ci/lint', anchor: 'simulate-a-pipeline'), "total-branches" => total_branches, "validate-tab-illustration-path" => image_path('illustrations/project-run-CICD-pipelines-sm.svg'), "yml-help-page-path" => help_page_path('ci/yaml/index') diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb index 3c3179f6fbe..33b771eef69 100644 --- a/app/helpers/commits_helper.rb +++ b/app/helpers/commits_helper.rb @@ -184,7 +184,7 @@ module CommitsHelper def diff_mode_swap_button(mode, file_hash) icon = mode == 'raw' ? 'doc-code' : 'doc-text' - entity = mode == 'raw' ? 'toHideBtn' : 'toShowBtn' + entity = mode == 'raw' ? 'rawButton' : 'renderedButton' title = "Display #{mode} diff" link_to("##{mode}-diff-#{file_hash}", diff --git a/app/helpers/diff_helper.rb b/app/helpers/diff_helper.rb index 71c8296ad2e..457502347ee 100644 --- a/app/helpers/diff_helper.rb +++ b/app/helpers/diff_helper.rb @@ -33,6 +33,7 @@ module DiffHelper if action_name == 'diff_for_path' options[:expanded] = true options[:paths] = params.values_at(:old_path, :new_path) + options[:use_extra_viewer_as_main] = false end options @@ -227,6 +228,7 @@ module DiffHelper def conflicts(allow_tree_conflicts: false) return unless options[:merge_ref_head_diff] + return unless merge_request.cannot_be_merged? conflicts_service = MergeRequests::Conflicts::ListService.new(merge_request, allow_tree_conflicts: allow_tree_conflicts) # rubocop:disable CodeReuse/ServiceClass diff --git a/app/helpers/emails_helper.rb b/app/helpers/emails_helper.rb index c23d905a008..54733fa9101 100644 --- a/app/helpers/emails_helper.rb +++ b/app/helpers/emails_helper.rb @@ -116,19 +116,16 @@ module EmailsHelper end end - # "You are receiving this email because #{reason} on #{gitlab_host}." - def notification_reason_text(reason) - gitlab_host = Gitlab.config.gitlab.host - - case reason - when NotificationReason::OWN_ACTIVITY - _("You're receiving this email because of your activity on %{host}.") % { host: gitlab_host } - when NotificationReason::ASSIGNED - _("You're receiving this email because you have been assigned an item on %{host}.") % { host: gitlab_host } - when NotificationReason::MENTIONED - _("You're receiving this email because you have been mentioned on %{host}.") % { host: gitlab_host } + # "You are receiving this email because ... on #{host}. ..." + def notification_reason_text(reason: nil, show_manage_notifications_link: false, show_help_link: false, manage_label_subscriptions_url: nil, unsubscribe_url: nil, format: :text) + if unsubscribe_url && show_manage_notifications_link && show_help_link + notification_reason_text_with_unsubscribe_and_manage_notifications_and_help_links(reason: reason, unsubscribe_url: unsubscribe_url, format: format) + elsif !reason && manage_label_subscriptions_url && show_help_link + notification_reason_text_with_manage_label_subscriptions_and_help_links(manage_label_subscriptions_url: manage_label_subscriptions_url, format: format) + elsif show_manage_notifications_link && show_help_link + notification_reason_text_with_manage_notifications_and_help_links(reason: reason, format: format) else - _("You're receiving this email because of your account on %{host}.") % { host: gitlab_host } + notification_reason_text_without_links(reason: reason, format: format) end end @@ -259,9 +256,7 @@ module EmailsHelper end def instance_access_request_text(user, format: nil) - gitlab_host = Gitlab.config.gitlab.host - - _('%{username} has asked for a GitLab account on your instance %{host}:') % { username: sanitize_name(user.name), host: gitlab_host } + _('%{username} has asked for a GitLab account on your instance %{host}:').html_safe % { username: sanitize_name(user.name), host: gitlab_host_link(format) } end def instance_access_request_link(user, format: nil) @@ -276,6 +271,14 @@ module EmailsHelper end end + def link_start(url) + '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: url } + end + + def link_end + '</a>'.html_safe + end + def contact_your_administrator_text _('Please contact your administrator with any questions.') end @@ -317,6 +320,75 @@ module EmailsHelper def email_header_and_footer_enabled? current_appearance&.email_header_and_footer_enabled? end + + def gitlab_host_link(format) + case format + when :html + generate_link(Gitlab.config.gitlab.host, Gitlab.config.gitlab.url) + when :text + Gitlab.config.gitlab.host + end + end + + def notification_reason_text_with_unsubscribe_and_manage_notifications_and_help_links(reason:, unsubscribe_url:, format:) + unsubscribe_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: unsubscribe_url } + unsubscribe_link_end = '</a>'.html_safe + + manage_notifications_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer" class="mng-notif-link">'.html_safe % { url: profile_notifications_url } + manage_notifications_link_end = '</a>'.html_safe + + help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer" class="help-link">'.html_safe % { url: help_url } + help_link_end = '</a>'.html_safe + + case reason + when NotificationReason::OWN_ACTIVITY + _("You're receiving this email because of your activity on %{host}. %{unsubscribe_link_start}Unsubscribe%{unsubscribe_link_end} from this thread · %{manage_notifications_link_start}Manage all notifications%{manage_notifications_link_end} · %{help_link_start}Help%{help_link_end}").html_safe % { host: gitlab_host_link(format), unsubscribe_link_start: unsubscribe_link_start, unsubscribe_link_end: unsubscribe_link_end, manage_notifications_link_start: manage_notifications_link_start, manage_notifications_link_end: manage_notifications_link_end, help_link_start: help_link_start, help_link_end: help_link_end } + when NotificationReason::ASSIGNED + _("You're receiving this email because you have been assigned an item on %{host}. %{unsubscribe_link_start}Unsubscribe%{unsubscribe_link_end} from this thread · %{manage_notifications_link_start}Manage all notifications%{manage_notifications_link_end} · %{help_link_start}Help%{help_link_end}").html_safe % { host: gitlab_host_link(format), unsubscribe_link_start: unsubscribe_link_start, unsubscribe_link_end: unsubscribe_link_end, manage_notifications_link_start: manage_notifications_link_start, manage_notifications_link_end: manage_notifications_link_end, help_link_start: help_link_start, help_link_end: help_link_end } + when NotificationReason::MENTIONED + _("You're receiving this email because you have been mentioned on %{host}. %{unsubscribe_link_start}Unsubscribe%{unsubscribe_link_end} from this thread · %{manage_notifications_link_start}Manage all notifications%{manage_notifications_link_end} · %{help_link_start}Help%{help_link_end}").html_safe % { host: gitlab_host_link(format), unsubscribe_link_start: unsubscribe_link_start, unsubscribe_link_end: unsubscribe_link_end, manage_notifications_link_start: manage_notifications_link_start, manage_notifications_link_end: manage_notifications_link_end, help_link_start: help_link_start, help_link_end: help_link_end } + else + _("You're receiving this email because of your account on %{host}. %{unsubscribe_link_start}Unsubscribe%{unsubscribe_link_end} from this thread · %{manage_notifications_link_start}Manage all notifications%{manage_notifications_link_end} · %{help_link_start}Help%{help_link_end}").html_safe % { host: gitlab_host_link(format), unsubscribe_link_start: unsubscribe_link_start, unsubscribe_link_end: unsubscribe_link_end, manage_notifications_link_start: manage_notifications_link_start, manage_notifications_link_end: manage_notifications_link_end, help_link_start: help_link_start, help_link_end: help_link_end } + end + end + + def notification_reason_text_with_manage_label_subscriptions_and_help_links(manage_label_subscriptions_url:, format:) + manage_label_subscriptions_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer" class="mng-notif-link">'.html_safe % { url: manage_label_subscriptions_url } + manage_label_subscriptions_link_end = '</a>'.html_safe + + help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer" class="help-link">'.html_safe % { url: help_url } + help_link_end = '</a>'.html_safe + + _("You're receiving this email because of your account on %{host}. %{manage_label_subscriptions_link_start}Manage label subscriptions%{manage_label_subscriptions_link_end} · %{help_link_start}Help%{help_link_end}").html_safe % { host: gitlab_host_link(format), manage_label_subscriptions_link_start: manage_label_subscriptions_link_start, manage_label_subscriptions_link_end: manage_label_subscriptions_link_end, help_link_start: help_link_start, help_link_end: help_link_end } + end + + def notification_reason_text_with_manage_notifications_and_help_links(reason:, format:) + manage_notifications_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer" class="mng-notif-link">'.html_safe % { url: profile_notifications_url } + manage_notifications_link_end = '</a>'.html_safe + + help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer" class="help-link">'.html_safe % { url: help_url } + help_link_end = '</a>'.html_safe + + case reason + when NotificationReason::MENTIONED + _("You're receiving this email because you have been mentioned on %{host}. %{manage_notifications_link_start}Manage all notifications%{manage_notifications_link_end} · %{help_link_start}Help%{help_link_end}").html_safe % { host: gitlab_host_link(format), manage_notifications_link_start: manage_notifications_link_start, manage_notifications_link_end: manage_notifications_link_end, help_link_start: help_link_start, help_link_end: help_link_end } + else + _("You're receiving this email because of your account on %{host}. %{manage_notifications_link_start}Manage all notifications%{manage_notifications_link_end} · %{help_link_start}Help%{help_link_end}").html_safe % { host: gitlab_host_link(format), manage_notifications_link_start: manage_notifications_link_start, manage_notifications_link_end: manage_notifications_link_end, help_link_start: help_link_start, help_link_end: help_link_end } + end + end + + def notification_reason_text_without_links(reason:, format:) + case reason + when NotificationReason::OWN_ACTIVITY + _("You're receiving this email because of your activity on %{host}.").html_safe % { host: gitlab_host_link(format) } + when NotificationReason::ASSIGNED + _("You're receiving this email because you have been assigned an item on %{host}.").html_safe % { host: gitlab_host_link(format) } + when NotificationReason::MENTIONED + _("You're receiving this email because you have been mentioned on %{host}.").html_safe % { host: gitlab_host_link(format) } + else + _("You're receiving this email because of your account on %{host}.").html_safe % { host: gitlab_host_link(format) } + end + end end EmailsHelper.prepend_mod_with('EmailsHelper') diff --git a/app/helpers/environments_helper.rb b/app/helpers/environments_helper.rb index 59d43c51db2..2623e32dbc8 100644 --- a/app/helpers/environments_helper.rb +++ b/app/helpers/environments_helper.rb @@ -36,7 +36,6 @@ module EnvironmentsHelper "environment_name": environment.name, "environments_path": api_v4_projects_environments_path(id: project.id), "environment_id": environment.id, - "cluster_applications_documentation_path" => help_page_path('user/clusters/integrations.md', anchor: 'elastic-stack-cluster-integration'), "clusters_path": project_clusters_path(project, format: :json) } end diff --git a/app/helpers/groups/group_members_helper.rb b/app/helpers/groups/group_members_helper.rb index 37b23345d2a..2021961772a 100644 --- a/app/helpers/groups/group_members_helper.rb +++ b/app/helpers/groups/group_members_helper.rb @@ -9,7 +9,7 @@ module Groups::GroupMembersHelper { multiple: true, class: 'input-clamp qa-member-select-field ', scope: :all, email_user: true } end - def group_members_app_data(group, members:, invited:, access_requests:, include_relations:, search:) + def group_members_app_data(group, members:, invited:, access_requests:, banned:, include_relations:, search:) { 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, include_relations, search), diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb index 9ea9509bc28..9d152416b2e 100644 --- a/app/helpers/groups_helper.rb +++ b/app/helpers/groups_helper.rb @@ -126,7 +126,7 @@ module GroupsHelper group.root? && current_user.can?(:admin_setting_to_allow_project_access_token_creation, group) end - def show_thanks_for_purchase_banner? + def show_thanks_for_purchase_alert? params.key?(:purchased_quantity) && params[:purchased_quantity].to_i > 0 end diff --git a/app/helpers/integrations_helper.rb b/app/helpers/integrations_helper.rb index 8d5523464c7..a1512d40235 100644 --- a/app/helpers/integrations_helper.rb +++ b/app/helpers/integrations_helper.rb @@ -216,7 +216,7 @@ module IntegrationsHelper end def fields_for_integration(integration) - Integrations::FieldSerializer.new(integration: integration).represent(integration.global_fields).to_json + Integrations::FieldSerializer.new(integration: integration).represent(integration.form_fields).to_json end def integration_level(integration) diff --git a/app/helpers/learn_gitlab_helper.rb b/app/helpers/learn_gitlab_helper.rb index 890f7f099df..421cf84f98c 100644 --- a/app/helpers/learn_gitlab_helper.rb +++ b/app/helpers/learn_gitlab_helper.rb @@ -4,6 +4,7 @@ module LearnGitlabHelper IMAGE_PATH_PLAN = "learn_gitlab/section_plan.svg" IMAGE_PATH_DEPLOY = "learn_gitlab/section_deploy.svg" IMAGE_PATH_WORKSPACE = "learn_gitlab/section_workspace.svg" + LICENSE_SCANNING_RUN_URL = 'https://docs.gitlab.com/ee/user/compliance/license_compliance/index.html' def learn_gitlab_enabled?(project) return false unless current_user @@ -64,7 +65,7 @@ module LearnGitlabHelper git_write: project_path(project), merge_request_created: project_merge_requests_path(project), user_added: project_members_url(project), - security_scan_enabled: project_security_configuration_path(project) + **deploy_section_action_urls(project) ) end @@ -72,6 +73,23 @@ module LearnGitlabHelper LearnGitlab::Onboarding::ACTION_ISSUE_IDS.transform_values { |id| project_issue_url(learn_gitlab_project, id) } end + def deploy_section_action_urls(project) + experiment(:security_actions_continuous_onboarding, + namespace: project.namespace, + user: current_user, + sticky_to: current_user + ) do |e| + e.control { { security_scan_enabled: project_security_configuration_path(project) } } + e.candidate do + { + license_scanning_run: LICENSE_SCANNING_RUN_URL, + secure_dependency_scanning_run: project_security_configuration_path(project, anchor: 'dependency-scanning'), + secure_dast_run: project_security_configuration_path(project, anchor: 'dast') + } + end + end.run + end + def learn_gitlab_project @learn_gitlab_project ||= LearnGitlab::Project.new(current_user).project end diff --git a/app/helpers/markup_helper.rb b/app/helpers/markup_helper.rb index 777d485797f..6077a059f6f 100644 --- a/app/helpers/markup_helper.rb +++ b/app/helpers/markup_helper.rb @@ -8,8 +8,8 @@ module MarkupHelper # Let's increase the render timeout # For a smaller one, a test that renders the blob content statically fails - # We can consider removing this custom timeout when refactor_blob_viewer FF is removed: - # https://gitlab.com/gitlab-org/gitlab/-/issues/324351 + # We can consider removing this custom timeout when markup_rendering_timeout FF is removed: + # https://gitlab.com/gitlab-org/gitlab/-/issues/365358 RENDER_TIMEOUT = 5.seconds def plain?(filename) diff --git a/app/helpers/namespace_storage_limit_alert_helper.rb b/app/helpers/namespace_storage_limit_alert_helper.rb deleted file mode 100644 index ed11f89a7dd..00000000000 --- a/app/helpers/namespace_storage_limit_alert_helper.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -module NamespaceStorageLimitAlertHelper - # Overridden in EE - def display_namespace_storage_limit_alert! - end -end - -NamespaceStorageLimitAlertHelper.prepend_mod_with('NamespaceStorageLimitAlertHelper') diff --git a/app/helpers/nav/new_dropdown_helper.rb b/app/helpers/nav/new_dropdown_helper.rb index 469d6c1a7eb..fb8fafe59f3 100644 --- a/app/helpers/nav/new_dropdown_helper.rb +++ b/app/helpers/nav/new_dropdown_helper.rb @@ -16,7 +16,7 @@ module Nav menu_sections.push(general_menu_section) { - title: _("Create new"), + title: _("Create new..."), menu_sections: menu_sections.select { |x| x.fetch(:menu_items).any? } } end diff --git a/app/helpers/packages_helper.rb b/app/helpers/packages_helper.rb index 20d40626449..ec64746d6b6 100644 --- a/app/helpers/packages_helper.rb +++ b/app/helpers/packages_helper.rb @@ -53,4 +53,14 @@ module PackagesHelper project.container_expiration_policy.nil? && project.container_repositories.exists? end + + def show_container_registry_settings(project) + Gitlab.config.registry.enabled && + Ability.allowed?(current_user, :admin_container_image, project) + end + + def show_package_registry_settings(project) + Gitlab.config.packages.enabled && + Ability.allowed?(current_user, :admin_package, project) + end end diff --git a/app/helpers/projects/pipeline_helper.rb b/app/helpers/projects/pipeline_helper.rb index eeee8290914..3b3fe13e58a 100644 --- a/app/helpers/projects/pipeline_helper.rb +++ b/app/helpers/projects/pipeline_helper.rb @@ -4,7 +4,7 @@ module Projects module PipelineHelper extend ::Ci::BuildsHelper - def js_pipeline_tabs_data(project, pipeline) + def js_pipeline_tabs_data(project, pipeline, _user) { can_generate_codequality_reports: pipeline.can_generate_codequality_reports?.to_json, failed_jobs_count: pipeline.failed_builds.count, diff --git a/app/helpers/projects/project_members_helper.rb b/app/helpers/projects/project_members_helper.rb index d5cc2b72ae9..51a7d3e35d0 100644 --- a/app/helpers/projects/project_members_helper.rb +++ b/app/helpers/projects/project_members_helper.rb @@ -1,10 +1,10 @@ # frozen_string_literal: true module Projects::ProjectMembersHelper - def project_members_app_data_json(project, members:, group_links:, invited:, access_requests:) + def project_members_app_data_json(project, members:, invited:, access_requests:, include_relations:, search:) { user: project_members_list_data(project, members, { param_name: :page, params: { search_groups: nil } }), - group: project_group_links_list_data(project, group_links), + group: project_group_links_list_data(project, include_relations, search), 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, @@ -57,10 +57,29 @@ module Projects::ProjectMembersHelper } end - def project_group_links_list_data(project, group_links) + def project_group_links_list_data(project, include_relations, search) + members = [] + + if include_relations.include?(:direct) + project_group_links = project.project_group_links + project_group_links = project_group_links.search(search) if search + members += project_group_links_serialized(project, project_group_links) + end + + if include_relations.include?(:inherited) + group_group_links = project.group_group_links.distinct_on_shared_with_group_id_with_group_access + group_group_links = group_group_links.search(search) if search + members += group_group_links_serialized(project, group_group_links) + end + + if project_group_links.present? && group_group_links.present? + members = members.sort_by { |m| -m.dig(:access_level, :integer_value).to_i } + .uniq { |m| m.dig(:shared_with_group, :id) } + end + { - members: project_group_links_serialized(project, group_links), - pagination: members_pagination_data(group_links), + members: members, + pagination: members_pagination_data(members), member_path: project_group_link_path(project, ':id') } end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 95e91a7ba27..2ece3e87500 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -377,7 +377,7 @@ module ProjectsHelper 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'), + visibilityHelpPath: help_page_path('user/public_access'), registryAvailable: Gitlab.config.registry.enabled, registryHelpPath: help_page_path('user/packages/container_registry/index'), lfsAvailable: Gitlab.config.lfs.enabled, @@ -388,7 +388,8 @@ module ProjectsHelper 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') + issuesHelpPath: help_page_path('user/project/issues/index'), + membersPagePath: project_project_members_path(project) } end @@ -684,7 +685,6 @@ module ProjectsHelper product_analytics metrics_dashboard feature_flags - tracings terraform ] end diff --git a/app/helpers/releases_helper.rb b/app/helpers/releases_helper.rb index a516ac85131..50089c7edab 100644 --- a/app/helpers/releases_helper.rb +++ b/app/helpers/releases_helper.rb @@ -53,12 +53,14 @@ module ReleasesHelper def data_for_edit_release_page new_edit_pages_shared_data.merge( tag_name: @release.tag, - releases_page_path: project_releases_path(@project, anchor: @release.tag) + releases_page_path: project_releases_path(@project, anchor: @release.tag), + delete_release_docs_path: releases_help_page_path(anchor: 'delete-a-release') ) end def data_for_new_release_page new_edit_pages_shared_data.merge( + tag_name: params[:tag_name], default_branch: @project.default_branch, releases_page_path: project_releases_path(@project) ) @@ -81,7 +83,8 @@ module ReleasesHelper release_assets_docs_path: releases_help_page_path(anchor: 'release-assets'), manage_milestones_path: project_milestones_path(@project), new_milestone_path: new_project_milestone_path(@project), - edit_release_docs_path: releases_help_page_path(anchor: 'edit-a-release') + edit_release_docs_path: releases_help_page_path(anchor: 'edit-a-release'), + upcoming_release_docs_path: releases_help_page_path(anchor: 'upcoming-releases') } end end diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb index c8750cd9b52..ecbcaec27bc 100644 --- a/app/helpers/search_helper.rb +++ b/app/helpers/search_helper.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true module SearchHelper + # params which should persist when a new tab is selected SEARCH_GENERIC_PARAMS = [ :search, :scope, @@ -129,7 +130,7 @@ module SearchHelper end def search_service - @search_service ||= ::SearchService.new(current_user, params.merge(confidential: Gitlab::Utils.to_boolean(params[:confidential]))) + @search_service ||= ::SearchService.new(current_user, sanitized_search_params) end def search_sort_options @@ -169,7 +170,7 @@ module SearchHelper # search_context exposes a bit too much data to the frontend, this controls what data we share and when. def header_search_context {}.tap do |hash| - hash[:group] = { id: search_context.group.id, name: search_context.group.name } if search_context.for_group? + hash[:group] = { id: search_context.group.id, name: search_context.group.name, full_name: search_context.group.full_name } if search_context.for_group? hash[:group_metadata] = search_context.group_metadata if search_context.for_group? hash[:project] = { id: search_context.project.id, name: search_context.project.name } if search_context.for_project? @@ -207,10 +208,10 @@ module SearchHelper { category: "Help", label: _("API Help"), url: help_page_path("api/index") }, { 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: _("Public Access Help"), url: help_page_path("user/public_access") }, { 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: _("SSH Keys Help"), url: help_page_path("user/ssh") }, + { category: "Help", label: _("System Hooks Help"), url: help_page_path("administration/system_hooks") }, { category: "Help", label: _("Webhooks Help"), url: help_page_path("user/project/integrations/webhooks") } ] end @@ -481,6 +482,13 @@ module SearchHelper def feature_flag_tab_enabled?(flag) @group || Feature.enabled?(flag, current_user, type: :ops) end + + def sanitized_search_params + sanitized_params = params.dup + sanitized_params[:confidential] = Gitlab::Utils.to_boolean(sanitized_params[:confidential]) if sanitized_params.key?(:confidential) + + sanitized_params + end end SearchHelper.prepend_mod_with('SearchHelper') diff --git a/app/helpers/sessions_helper.rb b/app/helpers/sessions_helper.rb index f0389000eb3..129180d1ccf 100644 --- a/app/helpers/sessions_helper.rb +++ b/app/helpers/sessions_helper.rb @@ -39,4 +39,16 @@ module SessionsHelper # 2. https://github.com/redis-store/redis-store/blob/3acfa95f4eb6260c714fdb00a3d84be8eedc13b2/lib/redis/store/ttl.rb#L32 request.env['rack.session.options'][:expire_after] = expiry_s end + + def send_rate_limited?(user) + Gitlab::ApplicationRateLimiter.peek(:email_verification_code_send, scope: user) + end + + def obfuscated_email(email) + regex = ::Gitlab::UntrustedRegexp.new('^(..?)(.*)(@.?)(.*)(\..*)$') + match = regex.match(email) + return email unless match + + match[1] + '*' * match[2].length + match[3] + '*' * match[4].length + match[5] + end end diff --git a/app/helpers/sorting_helper.rb b/app/helpers/sorting_helper.rb index 6f15cc7f4ec..ef79e2bc86f 100644 --- a/app/helpers/sorting_helper.rb +++ b/app/helpers/sorting_helper.rb @@ -254,6 +254,7 @@ module SortingHelper options = [ { value: sort_value_priority, text: sort_title_priority, href: page_filter_path(sort: sort_value_priority) }, { value: sort_value_created_date, text: sort_title_created_date, href: page_filter_path(sort: sort_value_created_date) }, + { value: sort_value_closed_date, text: sort_title_closed_date, href: page_filter_path(sort: sort_value_closed_date) }, { value: sort_value_recently_updated, text: sort_title_recently_updated, href: page_filter_path(sort: sort_value_recently_updated) }, { value: sort_value_milestone, text: sort_title_milestone, href: page_filter_path(sort: sort_value_milestone) } ] @@ -261,7 +262,7 @@ module SortingHelper options.concat([due_date_option]) if viewing_issues options.concat([popularity_option, label_priority_option]) - options.concat([merged_option, closed_option]) if viewing_merge_requests + options.concat([merged_option]) if viewing_merge_requests options.concat([relative_position_option]) if viewing_issues options.concat([title_option]) @@ -287,10 +288,6 @@ module SortingHelper { value: sort_value_merged_date, text: sort_title_merged_date, href: page_filter_path(sort: sort_value_merged_date) } end - def closed_option - { value: sort_value_closed_date, text: sort_title_closed_date, href: page_filter_path(sort: sort_value_closed_date) } - end - def relative_position_option { value: sort_value_relative_position, text: sort_title_relative_position, href: page_filter_path(sort: sort_value_relative_position) } end diff --git a/app/helpers/storage_helper.rb b/app/helpers/storage_helper.rb index 38ae9b5b634..ca81d5af4af 100644 --- a/app/helpers/storage_helper.rb +++ b/app/helpers/storage_helper.rb @@ -27,10 +27,11 @@ module StorageHelper def storage_enforcement_banner_info(namespace) root_ancestor = namespace.root_ancestor - return unless can?(current_user, :admin_namespace, root_ancestor) + return unless can?(current_user, :maintain_namespace, root_ancestor) return if root_ancestor.paid? return unless future_enforcement_date?(root_ancestor) return if user_dismissed_storage_enforcement_banner?(root_ancestor) + return unless ::Feature.enabled?(:namespace_storage_limit_show_preenforcement_banner, root_ancestor) { text: html_escape_once(s_("UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. " \ diff --git a/app/helpers/todos_helper.rb b/app/helpers/todos_helper.rb index 8529959f73c..f87125af07d 100644 --- a/app/helpers/todos_helper.rb +++ b/app/helpers/todos_helper.rb @@ -66,7 +66,13 @@ module TodosHelper return _('design') if todo.for_design? return _('alert') if todo.for_alert? - todo.target_type.titleize.downcase + target_type = if todo.for_issue_or_work_item? + todo.target.issue_type + else + todo.target_type + end + + target_type.titleize.downcase end def todo_target_path(todo) @@ -80,6 +86,9 @@ module TodosHelper todos_design_path(todo, path_options) elsif todo.for_alert? details_project_alert_management_path(todo.project, todo.target) + elsif todo.for_issue_or_work_item? + path_options[:only_path] = true + Gitlab::UrlBuilder.build(todo.target, **path_options) else path = [todo.resource_parent, todo.target] diff --git a/app/helpers/tree_helper.rb b/app/helpers/tree_helper.rb index 2fef4ae98a9..370dbb10462 100644 --- a/app/helpers/tree_helper.rb +++ b/app/helpers/tree_helper.rb @@ -58,14 +58,6 @@ module TreeHelper "#{username}-#{ref}-patch-#{epoch}" end - def tree_edit_project(project = @project) - if can?(current_user, :push_code, project) - project - elsif current_user && current_user.already_forked?(project) - current_user.fork_of(project) - end - end - def edit_in_new_fork_notice_now _("You're not allowed to make changes to this project directly. "\ "A fork of this project is being created that you can make changes in, so you can submit a merge request.") @@ -111,16 +103,6 @@ module TreeHelper end end - def up_dir_path - file = File.join(@path, "..") - tree_join(@ref, file) - end - - # returns the relative path of the first subdir that doesn't have only one directory descendant - def flatten_tree(root_path, tree) - tree.flat_path.sub(%r{\A#{Regexp.escape(root_path)}/}, '') - end - def selected_branch @branch_name || tree_edit_branch end diff --git a/app/helpers/users/callouts_helper.rb b/app/helpers/users/callouts_helper.rb index b8231b02ac1..3dd6b3f4a80 100644 --- a/app/helpers/users/callouts_helper.rb +++ b/app/helpers/users/callouts_helper.rb @@ -9,9 +9,9 @@ module Users FEATURE_FLAGS_NEW_VERSION = 'feature_flags_new_version' REGISTRATION_ENABLED_CALLOUT = 'registration_enabled_callout' UNFINISHED_TAG_CLEANUP_CALLOUT = 'unfinished_tag_cleanup_callout' - MINUTE_LIMIT_BANNER = 'minute_limit_banner' SECURITY_NEWSLETTER_CALLOUT = 'security_newsletter_callout' REGISTRATION_ENABLED_CALLOUT_ALLOWED_CONTROLLER_PATHS = [/^root/, /^dashboard\S*/, /^admin\S*/].freeze + WEB_HOOK_DISABLED = 'web_hook_disabled' def show_gke_cluster_integration_callout?(project) active_nav_link?(controller: sidebar_operations_paths) && @@ -61,16 +61,31 @@ module Users !user_dismissed?(SECURITY_NEWSLETTER_CALLOUT) end - def minute_limit_banner_dismissed? - user_dismissed?(MINUTE_LIMIT_BANNER) + def web_hook_disabled_dismissed?(project) + return false unless project + + last_failure = Gitlab::Redis::SharedState.with do |redis| + key = "web_hooks:last_failure:project-#{project.id}" + redis.get(key) + end + + last_failure = DateTime.parse(last_failure) if last_failure + + user_dismissed?(WEB_HOOK_DISABLED, last_failure, namespace: project.namespace) end private - def user_dismissed?(feature_name, ignore_dismissal_earlier_than = nil) + def user_dismissed?(feature_name, ignore_dismissal_earlier_than = nil, namespace: nil) return false unless current_user - current_user.dismissed_callout?(feature_name: feature_name, ignore_dismissal_earlier_than: ignore_dismissal_earlier_than) + query = { feature_name: feature_name, ignore_dismissal_earlier_than: ignore_dismissal_earlier_than } + + if namespace + current_user.dismissed_callout_for_namespace?(namespace: namespace, **query) + else + current_user.dismissed_callout?(**query) + end end end end diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb index e46aa6a446c..4ea2512bc67 100644 --- a/app/helpers/users_helper.rb +++ b/app/helpers/users_helper.rb @@ -15,7 +15,7 @@ module UsersHelper end def user_email_help_text(user) - return 'We also use email for avatar detection if no avatar is uploaded' unless user.unconfirmed_email.present? + return 'We also use email for avatar detection if no avatar is uploaded.' unless user.unconfirmed_email.present? confirmation_link = link_to 'Resend confirmation e-mail', user_confirmation_path(user: { email: @user.unconfirmed_email }), method: :post diff --git a/app/helpers/visibility_level_helper.rb b/app/helpers/visibility_level_helper.rb index b49bd33a30b..1baeeda0ef7 100644 --- a/app/helpers/visibility_level_helper.rb +++ b/app/helpers/visibility_level_helper.rb @@ -126,7 +126,7 @@ module VisibilityLevelHelper def project_visibility_level_description(level) case level when Gitlab::VisibilityLevel::PRIVATE - _("Project access must be granted explicitly to each user. If this project is part of a group, access will be granted to members of the group.") + _("Project access must be granted explicitly to each user. If this project is part of a group, access is granted to members of the group.") when Gitlab::VisibilityLevel::INTERNAL _("The project can be accessed by any logged in user except external users.") when Gitlab::VisibilityLevel::PUBLIC diff --git a/app/helpers/web_hooks/web_hooks_helper.rb b/app/helpers/web_hooks/web_hooks_helper.rb new file mode 100644 index 00000000000..95122750c2f --- /dev/null +++ b/app/helpers/web_hooks/web_hooks_helper.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module WebHooks + module WebHooksHelper + EXPIRY_TTL = 1.hour + + def show_project_hook_failed_callout?(project:) + return false unless current_user + return false unless Feature.enabled?(:webhooks_failed_callout, project) + return false unless Feature.enabled?(:web_hooks_disable_failed, project) + return false unless Ability.allowed?(current_user, :read_web_hooks, project) + + # Assumes include of Users::CalloutsHelper + return false if web_hook_disabled_dismissed?(project) + + any_project_hook_failed?(project) # Most expensive query last + end + + private + + def any_project_hook_failed?(project) + Rails.cache.fetch("any_web_hook_failed:#{project.id}", expires_in: EXPIRY_TTL) do + ProjectHook.for_projects(project).disabled.exists? + end + end + end +end |