diff options
Diffstat (limited to 'app/helpers')
47 files changed, 399 insertions, 192 deletions
diff --git a/app/helpers/access_tokens_helper.rb b/app/helpers/access_tokens_helper.rb index 1d38262159f..d8d44601327 100644 --- a/app/helpers/access_tokens_helper.rb +++ b/app/helpers/access_tokens_helper.rb @@ -27,4 +27,10 @@ module AccessTokensHelper } }.to_json end + + def expires_at_field_data + {} + end end + +AccessTokensHelper.prepend_mod diff --git a/app/helpers/appearances_helper.rb b/app/helpers/appearances_helper.rb index 5ca360f38da..cb43d911a2f 100644 --- a/app/helpers/appearances_helper.rb +++ b/app/helpers/appearances_helper.rb @@ -38,6 +38,8 @@ module AppearancesHelper def brand_header_logo if current_appearance&.header_logo? image_tag current_appearance.header_logo_path, class: 'brand-header-logo' + elsif Feature.enabled?(:ukraine_support_tanuki) + render partial: 'shared/logo_ukraine', formats: :svg else render partial: 'shared/logo', formats: :svg end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index e675c01bcbb..feeedb0a501 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -18,6 +18,28 @@ module ApplicationHelper end end + def dispensable_render(...) + render(...) + rescue StandardError => error + if Feature.enabled?(:dispensable_render, default_enabled: :yaml) + Gitlab::ErrorTracking.track_and_raise_for_dev_exception(error) + nil + else + raise error + end + end + + def dispensable_render_if_exists(...) + render_if_exists(...) + rescue StandardError => error + if Feature.enabled?(:dispensable_render, default_enabled: :yaml) + Gitlab::ErrorTracking.track_and_raise_for_dev_exception(error) + nil + else + raise error + end + end + def partial_exists?(partial) lookup_context.exists?(partial, [], true) end diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb index fa9b3bfc912..a9c13b2fdeb 100644 --- a/app/helpers/application_settings_helper.rb +++ b/app/helpers/application_settings_helper.rb @@ -212,6 +212,7 @@ module ApplicationSettingsHelper :auto_devops_enabled, :auto_devops_domain, :container_expiration_policies_enable_historic_entries, + :container_registry_expiration_policies_caching, :container_registry_token_expire_delay, :default_artifacts_expire_in, :default_branch_name, @@ -423,7 +424,8 @@ module ApplicationSettingsHelper :sidekiq_job_limiter_compression_threshold_bytes, :sidekiq_job_limiter_limit_bytes, :suggest_pipeline_enabled, - :user_email_lookup_limit, + :search_rate_limit, + :search_rate_limit_unauthenticated, :users_get_by_id_limit, :users_get_by_id_limit_allowlist_raw, :runner_token_expiration_interval, @@ -463,7 +465,10 @@ module ApplicationSettingsHelper end def instance_clusters_enabled? - can?(current_user, :read_cluster, Clusters::Instance.new) + clusterable = Clusters::Instance.new + + Feature.enabled?(:certificate_based_clusters, clusterable, default_enabled: :yaml, type: :ops) && + can?(current_user, :read_cluster, clusterable) end def omnibus_protected_paths_throttle? diff --git a/app/helpers/auth_helper.rb b/app/helpers/auth_helper.rb index fb2fa547447..ba6c0380edf 100644 --- a/app/helpers/auth_helper.rb +++ b/app/helpers/auth_helper.rb @@ -178,7 +178,7 @@ module AuthHelper end def google_tag_manager_enabled? - return false unless Gitlab.dev_env_or_com? + return false unless Gitlab.com? if Feature.enabled?(:gtm_nonce, type: :ops) extra_config.has_key?('google_tag_manager_nonce_id') && diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb index f0e8ff7778e..fcf6a177984 100644 --- a/app/helpers/blob_helper.rb +++ b/app/helpers/blob_helper.rb @@ -65,40 +65,13 @@ module BlobHelper return unless blob = readable_blob(options, path, project, ref) common_classes = "btn gl-button btn-confirm js-edit-blob gl-ml-3 #{options[:extra_class]}" - data = { track_action: 'click_edit', track_label: 'edit' } - - if Feature.enabled?(:web_ide_primary_edit, project.group) - common_classes += " btn-inverted" - data[:track_property] = 'secondary' - end edit_button_tag(blob, common_classes, _('Edit'), edit_blob_path(project, ref, path, options), project, - ref, - data) - end - - def ide_edit_button(project = @project, ref = @ref, path = @path, blob:) - return unless blob - - common_classes = 'btn gl-button btn-confirm ide-edit-button gl-ml-3' - data = { track_action: 'click_edit_ide', track_label: 'web_ide' } - - unless Feature.enabled?(:web_ide_primary_edit, project.group) - common_classes += " btn-inverted" - data[:track_property] = 'secondary' - end - - edit_button_tag(blob, - common_classes, - _('Web IDE'), - ide_edit_path(project, ref, path), - project, - ref, - data) + ref) end def modify_file_button(project = @project, ref = @ref, path = @path, blob:, label:, action:, btn_class:, modal_type:) @@ -363,16 +336,16 @@ module BlobHelper content_tag(:span, button, class: 'has-tooltip', title: _('You can only edit files when you are on a branch'), data: { container: 'body' }) end - def edit_link_tag(link_text, edit_path, common_classes, data) - link_to link_text, edit_path, class: "#{common_classes}", data: data + def edit_link_tag(link_text, edit_path, common_classes) + link_to link_text, edit_path, class: "#{common_classes}" end - def edit_button_tag(blob, common_classes, text, edit_path, project, ref, data) + def edit_button_tag(blob, common_classes, text, edit_path, project, ref) if !on_top_of_branch?(project, ref) edit_disabled_button_tag(text, common_classes) # This condition only applies to users who are logged in elsif !current_user || (current_user && can_modify_blob?(blob, project, ref)) - edit_link_tag(text, edit_path, common_classes, data) + edit_link_tag(text, edit_path, common_classes) elsif can?(current_user, :fork_project, project) && can?(current_user, :create_merge_request_in, project) edit_fork_button_tag(common_classes, project, text, edit_blob_fork_params(edit_path)) end diff --git a/app/helpers/broadcast_messages_helper.rb b/app/helpers/broadcast_messages_helper.rb index 881e11b10ea..dda834ee2c5 100644 --- a/app/helpers/broadcast_messages_helper.rb +++ b/app/helpers/broadcast_messages_helper.rb @@ -1,14 +1,22 @@ # frozen_string_literal: true module BroadcastMessagesHelper + include Gitlab::Utils::StrongMemoize + def current_broadcast_banner_messages - BroadcastMessage.current_banner_messages(request.path).select do |message| + BroadcastMessage.current_banner_messages( + current_path: request.path, + user_access_level: current_user_access_level_for_project_or_group + ).select do |message| cookies["hide_broadcast_message_#{message.id}"].blank? end end def current_broadcast_notification_message - not_hidden_messages = BroadcastMessage.current_notification_messages(request.path).select do |message| + not_hidden_messages = BroadcastMessage.current_notification_messages( + current_path: request.path, + user_access_level: current_user_access_level_for_project_or_group + ).select do |message| cookies["hide_broadcast_message_#{message.id}"].blank? end not_hidden_messages.last @@ -61,4 +69,35 @@ module BroadcastMessagesHelper def broadcast_type_options BroadcastMessage.broadcast_types.keys.map { |w| [w.humanize, w] } end + + def target_access_level_options + BroadcastMessage::ALLOWED_TARGET_ACCESS_LEVELS.map do |access_level| + [Gitlab::Access.human_access(access_level), access_level] + end + end + + def target_access_levels_display(access_levels) + access_levels.map do |access_level| + Gitlab::Access.human_access(access_level) + end.join(', ') + end + + private + + def current_user_access_level_for_project_or_group + return if Feature.disabled?(:role_targeted_broadcast_messages, default_enabled: :yaml) + return unless current_user.present? + + strong_memoize(:current_user_access_level_for_project_or_group) do + if controller.is_a? Projects::ApplicationController + next unless @project + + @project.team.max_member_access(current_user.id) + elsif controller.is_a? Groups::ApplicationController + next unless @group + + @group.max_member_access_for_user(current_user) + end + end + end end diff --git a/app/helpers/ci/jobs_helper.rb b/app/helpers/ci/jobs_helper.rb index c0dca66bac8..14e52b120f3 100644 --- a/app/helpers/ci/jobs_helper.rb +++ b/app/helpers/ci/jobs_helper.rb @@ -14,8 +14,7 @@ module Ci "build_stage" => @build.stage, "log_state" => '', "build_options" => javascript_build_options, - "retry_outdated_job_docs_url" => help_page_path('ci/pipelines/settings', anchor: 'retry-outdated-jobs'), - "code_quality_help_url" => help_page_path('user/project/merge_requests/code_quality', anchor: 'troubleshooting') + "retry_outdated_job_docs_url" => help_page_path('ci/pipelines/settings', anchor: 'retry-outdated-jobs') } end diff --git a/app/helpers/ci/pipelines_helper.rb b/app/helpers/ci/pipelines_helper.rb index 6104a1256d5..8d2f83409be 100644 --- a/app/helpers/ci/pipelines_helper.rb +++ b/app/helpers/ci/pipelines_helper.rb @@ -78,6 +78,37 @@ module Ci pipeline.stuck? end + def pipelines_list_data(project, list_url) + artifacts_endpoint_placeholder = ':pipeline_artifacts_id' + + data = { + endpoint: list_url, + project_id: project.id, + default_branch_name: project.default_branch, + params: params.to_json, + artifacts_endpoint: downloadable_artifacts_project_pipeline_path(project, artifacts_endpoint_placeholder, format: :json), + artifacts_endpoint_placeholder: artifacts_endpoint_placeholder, + pipeline_schedule_url: pipeline_schedules_path(project), + empty_state_svg_path: image_path('illustrations/pipelines_empty.svg'), + error_state_svg_path: image_path('illustrations/pipelines_failed.svg'), + no_pipelines_svg_path: image_path('illustrations/pipelines_pending.svg'), + can_create_pipeline: can?(current_user, :create_pipeline, project).to_s, + new_pipeline_path: can?(current_user, :create_pipeline, project) && new_project_pipeline_path(project), + ci_lint_path: can?(current_user, :create_pipeline, project) && project_ci_lint_path(project), + reset_cache_path: can?(current_user, :admin_pipeline, project) && reset_cache_project_settings_ci_cd_path(project), + has_gitlab_ci: has_gitlab_ci?(project).to_s, + pipeline_editor_path: can?(current_user, :create_pipeline, project) && project_ci_pipeline_editor_path(project), + suggested_ci_templates: suggested_ci_templates.to_json, + ci_runner_settings_path: project_settings_ci_cd_path(project, ci_runner_templates: true, anchor: 'js-runners-settings') + } + + experiment(:runners_availability_section, namespace: project.root_ancestor) do |e| + e.candidate { data[:any_runners_available] = project.active_runners.exists?.to_s } + end + + data + end + private def warning_markdown(pipeline) diff --git a/app/helpers/clusters_helper.rb b/app/helpers/clusters_helper.rb index 1475a26ca09..959dac1254e 100644 --- a/app/helpers/clusters_helper.rb +++ b/app/helpers/clusters_helper.rb @@ -1,17 +1,6 @@ # frozen_string_literal: true module ClustersHelper - def create_new_cluster_label(provider: nil) - case provider - when 'aws' - s_('ClusterIntegration|Create new cluster on EKS') - when 'gcp' - s_('ClusterIntegration|Create new cluster on GKE') - else - s_('ClusterIntegration|Create new cluster') - end - end - def display_cluster_agents?(clusterable) clusterable.is_a?(Project) end @@ -26,22 +15,19 @@ module ClustersHelper gcp: { path: image_path('illustrations/logos/google_gke.svg'), text: s_('ClusterIntegration|Google GKE') } }, clusters_empty_state_image: image_path('illustrations/empty-state/empty-state-clusters.svg'), + empty_state_image: image_path('illustrations/empty-state/empty-state-agents.svg'), empty_state_help_text: clusterable.empty_state_help_text, - new_cluster_path: clusterable.new_path(tab: 'create'), + new_cluster_path: clusterable.new_path, + add_cluster_path: clusterable.connect_path, can_add_cluster: clusterable.can_add_cluster?.to_s, - can_admin_cluster: clusterable.can_admin_cluster?.to_s - } - end - - def js_clusters_data(clusterable) - { - default_branch_name: clusterable.default_branch, - empty_state_image: image_path('illustrations/empty-state/empty-state-agents.svg'), - project_path: clusterable.full_path, - add_cluster_path: clusterable.new_path(tab: 'add'), + can_admin_cluster: clusterable.can_admin_cluster?.to_s, + display_cluster_agents: display_cluster_agents?(clusterable).to_s, + certificate_based_clusters_enabled: Feature.enabled?(:certificate_based_clusters, clusterable, default_enabled: :yaml, type: :ops).to_s, + default_branch_name: default_branch_name(clusterable), + project_path: clusterable_project_path(clusterable), kas_address: Gitlab::Kas.external_url, gitlab_version: Gitlab.version_info - }.merge(js_clusters_list_data(clusterable)) + } end def js_cluster_form_data(cluster, can_edit) @@ -122,4 +108,14 @@ module ClustersHelper def can_admin_cluster?(user, cluster) can?(user, :admin_cluster, cluster) end + + private + + def default_branch_name(clusterable) + clusterable.default_branch if clusterable.is_a?(Project) + end + + def clusterable_project_path(clusterable) + clusterable.full_path if clusterable.is_a?(Project) + end end diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb index 43e727ac483..c78e906e052 100644 --- a/app/helpers/commits_helper.rb +++ b/app/helpers/commits_helper.rb @@ -182,6 +182,19 @@ module CommitsHelper project_commit_path(project, DEFAULT_SHA).sub("/#{DEFAULT_SHA}", '/$COMMIT_SHA') end + def diff_mode_swap_button(mode, file_hash) + icon = mode == 'raw' ? 'doc-code' : 'doc-text' + entity = mode == 'raw' ? 'toHideBtn' : 'toShowBtn' + title = "Display #{mode} diff" + + link_to("##{mode}-diff-#{file_hash}", + class: "btn gl-button btn-default btn-file-option has-tooltip btn-show-#{mode}-diff", + title: title, + data: { file_hash: file_hash, diff_toggle_entity: entity }) do + sprite_icon(icon) + end + end + protected # Private: Returns a link to a person. If the person has a matching user and diff --git a/app/helpers/container_expiration_policies_helper.rb b/app/helpers/container_expiration_policies_helper.rb index 52f68ac53f0..0005682e979 100644 --- a/app/helpers/container_expiration_policies_helper.rb +++ b/app/helpers/container_expiration_policies_helper.rb @@ -25,8 +25,7 @@ module ContainerExpirationPoliciesHelper end end - def container_expiration_policies_historic_entry_enabled?(project) - Gitlab::CurrentSettings.container_expiration_policies_enable_historic_entries || - Feature.enabled?(:container_expiration_policies_historic_entry, project) + def container_expiration_policies_historic_entry_enabled? + Gitlab::CurrentSettings.container_expiration_policies_enable_historic_entries end end diff --git a/app/helpers/container_registry_helper.rb b/app/helpers/container_registry_helper.rb index 1b77b639ce1..255b8183164 100644 --- a/app/helpers/container_registry_helper.rb +++ b/app/helpers/container_registry_helper.rb @@ -2,8 +2,7 @@ module ContainerRegistryHelper def container_registry_expiration_policies_throttling? - Feature.enabled?(:container_registry_expiration_policies_throttling) && - ContainerRegistry::Client.supports_tag_delete? + Feature.enabled?(:container_registry_expiration_policies_throttling, default_enabled: :yaml) end def container_repository_gid_prefix diff --git a/app/helpers/dashboard_helper.rb b/app/helpers/dashboard_helper.rb index f0e1f252917..bcb1f63840d 100644 --- a/app/helpers/dashboard_helper.rb +++ b/app/helpers/dashboard_helper.rb @@ -15,6 +15,10 @@ module DashboardHelper merge_requests_dashboard_path(reviewer_username: current_user.username) end + def attention_requested_mrs_dashboard_path + merge_requests_dashboard_path(attention: current_user.username) + end + def dashboard_nav_links @dashboard_nav_links ||= get_dashboard_nav_links end diff --git a/app/helpers/deploy_tokens_helper.rb b/app/helpers/deploy_tokens_helper.rb index d6fbe0b6b45..560d2fcd29f 100644 --- a/app/helpers/deploy_tokens_helper.rb +++ b/app/helpers/deploy_tokens_helper.rb @@ -16,4 +16,11 @@ module DeployTokensHelper Gitlab.config.packages.enabled && can?(current_user, :read_package, group_or_project) end + + def deploy_token_revoke_button_data(token:, group_or_project:) + { + token: token.to_json(only: [:id, :name]), + revoke_path: revoke_deploy_token_path(group_or_project, token) + } + end end diff --git a/app/helpers/diff_helper.rb b/app/helpers/diff_helper.rb index 2b5f726dad1..100d5c0281c 100644 --- a/app/helpers/diff_helper.rb +++ b/app/helpers/diff_helper.rb @@ -28,7 +28,7 @@ module DiffHelper end def diff_options - options = { ignore_whitespace_change: hide_whitespace?, expanded: diffs_expanded? } + options = { ignore_whitespace_change: hide_whitespace?, expanded: diffs_expanded?, use_extra_viewer_as_main: true } if action_name == 'diff_for_path' options[:expanded] = true @@ -74,7 +74,7 @@ module DiffHelper end def diff_link_number(line_type, match, text) - line_type == match ? " " : text + line_type == match || text == 0 ? " " : text end def parallel_diff_discussions(left, right, diff_file) diff --git a/app/helpers/dropdowns_helper.rb b/app/helpers/dropdowns_helper.rb index 0092743f96e..a910d3d7c9d 100644 --- a/app/helpers/dropdowns_helper.rb +++ b/app/helpers/dropdowns_helper.rb @@ -129,7 +129,7 @@ module DropdownsHelper end def dropdown_loading - spinner = loading_icon(container: true, size: "md", css_class: "gl-mt-7") + spinner = gl_loading_icon(size: "md", css_class: "gl-mt-7") content_tag(:div, spinner, class: "dropdown-loading") end end diff --git a/app/helpers/explore_helper.rb b/app/helpers/explore_helper.rb index 026dbd60ac6..1defe480059 100644 --- a/app/helpers/explore_helper.rb +++ b/app/helpers/explore_helper.rb @@ -19,26 +19,10 @@ module ExploreHelper request_path_with_options(options) end - def filter_audit_path(options = {}) - exist_opts = { - entity_type: params[:entity_type], - entity_id: params[:entity_id], - created_before: params[:created_before], - created_after: params[:created_after], - sort: params[:sort] - } - options = exist_opts.merge(options).delete_if { |key, value| value.blank? } - request_path_with_options(options) - end - def filter_groups_path(options = {}) request_path_with_options(options) end - def explore_controller? - controller.class.name.split("::").first == "Explore" - end - def explore_nav_links @explore_nav_links ||= get_explore_nav_links end @@ -47,14 +31,27 @@ module ExploreHelper explore_nav_links.include?(link) end - def any_explore_nav_link?(links) - links.any? { |link| explore_nav_link?(link) } - end - def public_visibility_restricted? Gitlab::VisibilityLevel.public_visibility_restricted? end + def projects_filter_items + [ + { value: _('Any'), text: _('Any'), href: filter_projects_path(visibility_level: nil) }, + *Gitlab::VisibilityLevel.options.keys.map do |key| + { + value: key, + text: key, + href: filter_projects_path(visibility_level: Gitlab::VisibilityLevel.options[key]) + } + end + ] + end + + def projects_filter_selected(visibility_level) + visibility_level.present? ? visibility_level_label(visibility_level.to_i) : _('Any') + end + private def get_explore_nav_links diff --git a/app/helpers/groups/crm_settings_helper.rb b/app/helpers/groups/crm_settings_helper.rb index ab47ec40b13..d7ca25a9d1b 100644 --- a/app/helpers/groups/crm_settings_helper.rb +++ b/app/helpers/groups/crm_settings_helper.rb @@ -2,7 +2,7 @@ module Groups module CrmSettingsHelper - def crm_feature_flag_enabled?(group) + def crm_feature_available?(group) Feature.enabled?(:customer_relations, group) end end diff --git a/app/helpers/groups/group_members_helper.rb b/app/helpers/groups/group_members_helper.rb index 07ab246b089..a719d80a1a1 100644 --- a/app/helpers/groups/group_members_helper.rb +++ b/app/helpers/groups/group_members_helper.rb @@ -9,10 +9,6 @@ module Groups::GroupMembersHelper { multiple: true, class: 'input-clamp qa-member-select-field ', scope: :all, email_user: true } end - def render_invite_member_for_group(group, default_access_level) - 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(group, members:, invited:, access_requests:) { user: group_members_list_data(group, members, { param_name: :page, params: { invited_members_page: nil, search_invited: nil } }), diff --git a/app/helpers/icons_helper.rb b/app/helpers/icons_helper.rb index 32d808c960c..6f7ac069fe4 100644 --- a/app/helpers/icons_helper.rb +++ b/app/helpers/icons_helper.rb @@ -49,13 +49,39 @@ module IconsHelper end end - def loading_icon(container: false, color: 'orange', size: 'sm', css_class: nil) - css_classes = ['gl-spinner', "gl-spinner-#{color}", "gl-spinner-#{size}"] - css_classes << "#{css_class}" unless css_class.blank? - - spinner = content_tag(:span, "", { class: css_classes.join(' '), aria: { label: _('Loading') } }) - - container == true ? content_tag(:div, spinner, { class: 'gl-spinner-container' }) : spinner + # Creates a GitLab UI loading icon/spinner. + # + # Examples: + # # Default + # gl_loading_icon + # + # # Sizes + # gl_loading_icon(size: 'md') + # gl_loading_icon(size: 'lg') + # gl_loading_icon(size: 'xl') + # + # # Colors + # gl_loading_icon(color: 'light') + # + # # Block/Inline + # gl_loading_icon(inline: true) + # + # # Custom classes + # gl_loading_icon(css_class: "foo-bar") + # + # See also https://gitlab-org.gitlab.io/gitlab-ui/?path=/story/base-loading-icon--default + def gl_loading_icon(inline: false, color: 'dark', size: 'sm', css_class: nil) + spinner = content_tag(:span, "", { + class: %[gl-spinner gl-spinner-#{color} gl-spinner-#{size} gl-vertical-align-text-bottom!], + aria: { label: _('Loading') } + }) + + container_classes = ['gl-spinner-container'] + container_classes << css_class unless css_class.blank? + content_tag(inline ? :span : :div, spinner, { + class: container_classes, + role: 'status' + }) end def external_snippet_icon(name) diff --git a/app/helpers/integrations_helper.rb b/app/helpers/integrations_helper.rb index f5ba978e860..b960ed46ba9 100644 --- a/app/helpers/integrations_helper.rb +++ b/app/helpers/integrations_helper.rb @@ -1,6 +1,35 @@ # frozen_string_literal: true module IntegrationsHelper + def integration_event_title(event) + case event + when "push", "push_events" + _("Push") + when "tag_push", "tag_push_events" + _("Tag push") + when "note", "note_events" + _("Note") + when "confidential_note", "confidential_note_events" + _("Confidential note") + when "issue", "issue_events" + _("Issue") + when "confidential_issue", "confidential_issue_events" + _("Confidential issue") + when "merge_request", "merge_request_events" + _("Merge request") + when "pipeline", "pipeline_events" + _("Pipeline") + when "wiki_page", "wiki_page_events" + _("Wiki page") + when "commit", "commit_events" + _("Commit") + when "deployment" + _("Deployment") + when "alert" + _("Alert") + end + end + def integration_event_description(integration, event) case integration when Integrations::Jira @@ -75,7 +104,8 @@ module IntegrationsHelper form_data = { id: integration.id, show_active: integration.show_active_box?.to_s, - activated: (integration.active || integration.new_record?).to_s, + activated: (integration.active || (integration.new_record? && integration.activate_disabled_reason.nil?)).to_s, + activate_disabled: integration.activate_disabled_reason.present?.to_s, type: integration.to_param, merge_request_events: integration.merge_requests_events.to_s, commit_events: integration.commit_events.to_s, @@ -83,6 +113,7 @@ module IntegrationsHelper comment_detail: integration.comment_detail, learn_more_path: integrations_help_page_path, trigger_events: trigger_events_for_integration(integration), + sections: integration.sections.to_json, fields: fields_for_integration(integration), inherit_from_id: integration.inherit_from_id, integration_level: integration_level(integration), diff --git a/app/helpers/invite_members_helper.rb b/app/helpers/invite_members_helper.rb index 1f225e9c0e5..a2dde29e25d 100644 --- a/app/helpers/invite_members_helper.rb +++ b/app/helpers/invite_members_helper.rb @@ -6,7 +6,7 @@ module InviteMembersHelper def can_invite_members_for_project?(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, default_enabled: :yaml) && can?(current_user, :admin_project_member, project) + can?(current_user, :admin_project_member, project) end def invite_accepted_notice(member) @@ -73,7 +73,7 @@ module InviteMembersHelper def show_invite_members_for_task?(source) return unless current_user - invite_for_help_continuous_onboarding = source.is_a?(Project) && experiment(:invite_for_help_continuous_onboarding, namespace: source.namespace).variant.name == 'candidate' + invite_for_help_continuous_onboarding = source.is_a?(Project) && experiment(:invite_for_help_continuous_onboarding, namespace: source.namespace).assigned.name == 'candidate' params[:open_modal] == 'invite_members_for_task' || invite_for_help_continuous_onboarding end diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb index 8e7f5060412..298162fe970 100644 --- a/app/helpers/issues_helper.rb +++ b/app/helpers/issues_helper.rb @@ -169,7 +169,7 @@ module IssuesHelper end def issue_header_actions_data(project, issuable, current_user) - new_issuable_params = { issue: { description: _('Related to #%{issue_id}.') % { issue_id: issuable.iid } + "\n\n" } } + new_issuable_params = { issue: {}, add_related_issue: issuable.iid } if issuable.incident? new_issuable_params[:issuable_template] = 'incident' new_issuable_params[:issue][:issue_type] = 'incident' @@ -209,7 +209,7 @@ module IssuesHelper } end - def project_issues_list_data(project, current_user, finder) + def project_issues_list_data(project, current_user) common_issues_list_data(project, current_user).merge( can_bulk_update: can?(current_user, :admin_issue, project).to_s, can_edit: can?(current_user, :admin_project, project).to_s, @@ -223,7 +223,7 @@ module IssuesHelper is_project: true.to_s, 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) }), + new_issue_path: new_project_issue_path(project), project_import_jira_path: project_import_jira_path(project), quick_actions_help_path: help_page_path('user/project/quick_actions'), releases_path: project_releases_path(project, format: :json), diff --git a/app/helpers/jira_connect_helper.rb b/app/helpers/jira_connect_helper.rb index 9a0f0944fd1..67b85b26f9e 100644 --- a/app/helpers/jira_connect_helper.rb +++ b/app/helpers/jira_connect_helper.rb @@ -9,12 +9,38 @@ module JiraConnectHelper subscriptions: subscriptions.map { |s| serialize_subscription(s) }.to_json, subscriptions_path: jira_connect_subscriptions_path, users_path: current_user ? nil : jira_connect_users_path, # users_path is used to determine if user is signed in - gitlab_user_path: current_user ? user_path(current_user) : nil + gitlab_user_path: current_user ? user_path(current_user) : nil, + oauth_metadata: Feature.enabled?(:jira_connect_oauth, current_user) ? jira_connect_oauth_data.to_json : nil } end private + def jira_connect_oauth_data + oauth_authorize_url = oauth_authorization_url( + client_id: ENV['JIRA_CONNECT_OAUTH_CLIENT_ID'], + response_type: 'code', + scope: 'api', + redirect_uri: jira_connect_oauth_callbacks_url, + state: oauth_state + ) + + { + oauth_authorize_url: oauth_authorize_url, + oauth_token_url: oauth_token_url, + state: oauth_state, + oauth_token_payload: { + grant_type: :authorization_code, + client_id: ENV['JIRA_CONNECT_OAUTH_CLIENT_ID'], + redirect_uri: jira_connect_oauth_callbacks_url + } + } + end + + def oauth_state + @oauth_state ||= SecureRandom.hex(32) + end + def serialize_subscription(subscription) { group: { diff --git a/app/helpers/labels_helper.rb b/app/helpers/labels_helper.rb index 2150729cb2a..877785c9eaf 100644 --- a/app/helpers/labels_helper.rb +++ b/app/helpers/labels_helper.rb @@ -61,7 +61,7 @@ module LabelsHelper render_label_text( label.name, suffix: suffix, - css_class: "gl-label-text #{text_color_class_for_bg(label.color)}", + css_class: "gl-label-text #{label.text_color_class}", bg_color: label.color ) end @@ -114,30 +114,8 @@ module LabelsHelper end end - def text_color_class_for_bg(bg_color) - if light_color?(bg_color) - 'gl-label-text-dark' - else - 'gl-label-text-light' - end - end - def text_color_for_bg(bg_color) - if light_color?(bg_color) - '#333333' - else - '#FFFFFF' - end - end - - def light_color?(color) - if color.length == 4 - r, g, b = color[1, 4].scan(/./).map { |v| (v * 2).hex } - else - r, g, b = color[1, 7].scan(/.{2}/).map(&:hex) - end - - (r + g + b) > 500 + ::Gitlab::Color.of(bg_color).contrast end def labels_filter_path_with_defaults(only_group_labels: false, include_ancestor_groups: true, include_descendant_groups: false) diff --git a/app/helpers/lazy_image_tag_helper.rb b/app/helpers/lazy_image_tag_helper.rb index 0c5744b46ae..d0bdaaae5f8 100644 --- a/app/helpers/lazy_image_tag_helper.rb +++ b/app/helpers/lazy_image_tag_helper.rb @@ -1,12 +1,15 @@ # frozen_string_literal: true module LazyImageTagHelper + include PreferencesHelper + def placeholder_image "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" end # Override the default ActionView `image_tag` helper to support lazy-loading def image_tag(source, options = {}) + source = options[:dark_variant] if options[:dark_variant] && user_application_dark_mode? options = options.symbolize_keys unless options.delete(:lazy) == false diff --git a/app/helpers/learn_gitlab_helper.rb b/app/helpers/learn_gitlab_helper.rb index 7dfd9ed47e3..60f3b12d736 100644 --- a/app/helpers/learn_gitlab_helper.rb +++ b/app/helpers/learn_gitlab_helper.rb @@ -1,6 +1,10 @@ # frozen_string_literal: true 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" + def learn_gitlab_enabled?(project) return false unless current_user @@ -25,19 +29,7 @@ module LearnGitlabHelper def onboarding_actions_data(project) attributes = onboarding_progress(project).attributes.symbolize_keys - urls_to_use = nil - - experiment( - :change_continuous_onboarding_link_urls, - namespace: project.namespace, - actor: current_user, - sticky_to: project.namespace - ) do |e| - e.control { urls_to_use = action_urls } - e.candidate { urls_to_use = new_action_urls(project) } - end - - urls_to_use.to_h do |action, url| + action_urls(project).to_h do |action, url| [ action, url: url, @@ -50,13 +42,13 @@ module LearnGitlabHelper def onboarding_sections_data { workspace: { - svg: image_path("learn_gitlab/section_workspace.svg") + svg: image_path(IMAGE_PATH_WORKSPACE) }, plan: { - svg: image_path("learn_gitlab/section_plan.svg") + svg: image_path(IMAGE_PATH_PLAN) }, deploy: { - svg: image_path("learn_gitlab/section_deploy.svg") + svg: image_path(IMAGE_PATH_DEPLOY) } } end @@ -65,22 +57,20 @@ module LearnGitlabHelper { name: project.name } end - def action_urls - LearnGitlab::Onboarding::ACTION_ISSUE_IDS.transform_values { |id| project_issue_url(learn_gitlab_project, id) } - .merge(LearnGitlab::Onboarding::ACTION_DOC_URLS) - end - - def new_action_urls(project) - action_urls.merge( + def action_urls(project) + action_issue_urls.merge( issue_created: project_issues_path(project), git_write: project_path(project), - pipeline_created: project_pipelines_path(project), merge_request_created: project_merge_requests_path(project), user_added: project_members_url(project), security_scan_enabled: project_security_configuration_path(project) ) end + def action_issue_urls + LearnGitlab::Onboarding::ACTION_ISSUE_IDS.transform_values { |id| project_issue_url(learn_gitlab_project, id) } + end + def learn_gitlab_project @learn_gitlab_project ||= LearnGitlab::Project.new(current_user).project end diff --git a/app/helpers/listbox_helper.rb b/app/helpers/listbox_helper.rb index d24680bc0b0..16caf862c7b 100644 --- a/app/helpers/listbox_helper.rb +++ b/app/helpers/listbox_helper.rb @@ -16,8 +16,10 @@ module ListboxHelper # the sort key), `text` is the user-facing string for the item, and `href` is # the path to redirect to when that item is selected. # - # The `selected` parameter is the currently selected `value`, and must - # correspond to one of the `items`, or be `nil`. When `selected.nil?`, the first item is selected. + # The `selected` parameter is the currently selected `value`, and should + # correspond to one of the `items`, or be `nil`. When `selected.nil?` or + # a value which does not correspond to one of the items, the first item is + # selected. # # The final parameter `html_options` applies arbitrary attributes to the # returned tag. Some of these are passed to the underlying Vue component as @@ -37,9 +39,12 @@ module ListboxHelper webpack_bundle_tag 'redirect_listbox' end - selected ||= items.first[:value] selected_option = items.find { |opt| opt[:value] == selected } - raise ArgumentError, "cannot find #{selected} in #{items}" unless selected_option + + unless selected_option + selected_option = items.first + selected = selected_option[:value] + end button = button_tag(type: :button, class: DROPDOWN_BUTTON_CLASSES) do content_tag(:span, selected_option[:text], class: DROPDOWN_INNER_CLASS) + diff --git a/app/helpers/markup_helper.rb b/app/helpers/markup_helper.rb index f16d9f6325b..7a4cc61af79 100644 --- a/app/helpers/markup_helper.rb +++ b/app/helpers/markup_helper.rb @@ -127,7 +127,7 @@ module MarkupHelper text = wiki_page.content return '' unless text.present? - context = render_wiki_content_context(@wiki, wiki_page, context) + context = render_wiki_content_context(wiki_page.wiki, wiki_page, context) html = markup_unsafe(wiki_page.path, text, context) prepare_for_rendering(html, context) @@ -181,7 +181,8 @@ module MarkupHelper wiki: wiki, repository: wiki.repository, page_slug: wiki_page.slug, - issuable_reference_expansion_enabled: true + issuable_reference_expansion_enabled: true, + requested_path: wiki_page.path ).merge(render_wiki_content_context_container(wiki)) end @@ -263,7 +264,7 @@ module MarkupHelper end def asciidoc_unsafe(text, context = {}) - context.merge!( + context.reverse_merge!( commit: @commit, ref: @ref, requested_path: @path diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb index abb7128470f..84a3802c72c 100644 --- a/app/helpers/merge_requests_helper.rb +++ b/app/helpers/merge_requests_helper.rb @@ -150,11 +150,20 @@ module MergeRequestsHelper review_requested_count = review_requested_merge_requests_count total_count = assigned_count + review_requested_count - { + counts = { assigned: assigned_count, review_requested: review_requested_count, total: total_count } + + if Feature.enabled?(:mr_attention_requests, default_enabled: :yaml) + attention_requested_count = attention_requested_merge_requests_count + + counts[:attention_requested_count] = attention_requested_count + counts[:total] = attention_requested_count + end + + counts end end @@ -205,6 +214,10 @@ module MergeRequestsHelper current_user.review_requested_open_merge_requests_count end + def attention_requested_merge_requests_count + current_user.attention_requested_open_merge_requests_count + end + def default_suggestion_commit_message @project.suggestion_commit_message.presence || Gitlab::Suggestions::CommitMessage::DEFAULT_SUGGESTION_COMMIT_MESSAGE end diff --git a/app/helpers/packages_helper.rb b/app/helpers/packages_helper.rb index 402a363349f..01075862618 100644 --- a/app/helpers/packages_helper.rb +++ b/app/helpers/packages_helper.rb @@ -50,8 +50,6 @@ module PackagesHelper Gitlab.com? && Gitlab.config.registry.enabled && project.feature_available?(:container_registry, current_user) && - !Gitlab::CurrentSettings.container_expiration_policies_enable_historic_entries && - Feature.enabled?(:container_expiration_policies_historic_entry, project) && project.container_expiration_policy.nil? && project.container_repositories.exists? end diff --git a/app/helpers/pagination_helper.rb b/app/helpers/pagination_helper.rb index 3167142e193..88bf09f0c03 100644 --- a/app/helpers/pagination_helper.rb +++ b/app/helpers/pagination_helper.rb @@ -22,4 +22,8 @@ module PaginationHelper def paginate_with_count(collection, remote: nil, total_pages: nil) paginate(collection, remote: remote, theme: 'gitlab', total_pages: total_pages) end + + def page_size + Kaminari.config.default_per_page + end end diff --git a/app/helpers/preferences_helper.rb b/app/helpers/preferences_helper.rb index 17450e5b26b..6a8c39b5b15 100644 --- a/app/helpers/preferences_helper.rb +++ b/app/helpers/preferences_helper.rb @@ -62,6 +62,10 @@ module PreferencesHelper @user_application_theme ||= Gitlab::Themes.for_user(current_user).css_class end + def user_application_dark_mode? + user_application_theme == 'gl-dark' + end + def user_application_theme_css_filename @user_application_theme_css_filename ||= Gitlab::Themes.for_user(current_user).css_filename end diff --git a/app/helpers/projects/cluster_agents_helper.rb b/app/helpers/projects/cluster_agents_helper.rb index 43d520d0eab..c17cb787c9f 100644 --- a/app/helpers/projects/cluster_agents_helper.rb +++ b/app/helpers/projects/cluster_agents_helper.rb @@ -7,7 +7,9 @@ module Projects::ClusterAgentsHelper agent_name: agent_name, can_admin_vulnerability: can?(current_user, :admin_vulnerability, project).to_s, empty_state_svg_path: image_path('illustrations/operations-dashboard_empty.svg'), - project_path: project.full_path + project_path: project.full_path, + kas_address: Gitlab::Kas.external_url, + can_admin_cluster: can?(current_user, :admin_cluster, project).to_s } end end diff --git a/app/helpers/projects/error_tracking_helper.rb b/app/helpers/projects/error_tracking_helper.rb index 5be4f67bde8..471565d162c 100644 --- a/app/helpers/projects/error_tracking_helper.rb +++ b/app/helpers/projects/error_tracking_helper.rb @@ -12,7 +12,8 @@ module Projects::ErrorTrackingHelper 'error-tracking-enabled' => error_tracking_enabled.to_s, 'project-path' => project.full_path, 'list-path' => project_error_tracking_index_path(project), - 'illustration-path' => image_path('illustrations/cluster_popover.svg') + 'illustration-path' => image_path('illustrations/cluster_popover.svg'), + 'show-integrated-tracking-disabled-alert' => show_integrated_tracking_disabled_alert?(project).to_s } end @@ -27,4 +28,15 @@ module Projects::ErrorTrackingHelper 'issue-stack-trace-path' => stack_trace_project_error_tracking_index_path(*opts) } end + + private + + def show_integrated_tracking_disabled_alert?(project) + return false if ::Feature.enabled?(:integrated_error_tracking, project) + + setting ||= project.error_tracking_setting || + project.build_error_tracking_setting + + setting.integrated_enabled? + end end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 6098ef63ec3..8a75f545a32 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -160,7 +160,7 @@ module ProjectsHelper end def link_to_autodeploy_doc - link_to _('About auto deploy'), help_page_path('topics/autodevops/stages.md', anchor: 'auto-deploy'), target: '_blank' + link_to _('About auto deploy'), help_page_path('topics/autodevops/stages.md', anchor: 'auto-deploy'), target: '_blank', rel: 'noopener' end def autodeploy_flash_notice(branch_name) @@ -431,19 +431,26 @@ module ProjectsHelper end def import_from_bitbucket_message - link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path("integration/bitbucket") } + configure_oauth_import_message('Bitbucket', help_page_path("integration/bitbucket")) + end + + def import_from_gitlab_message + configure_oauth_import_message('GitLab.com', help_page_path("integration/gitlab")) + end + private + + def configure_oauth_import_message(provider, help_url) str = if current_user.admin? - 'ImportProjects|To enable importing projects from Bitbucket, as administrator you need to configure %{link_start}OAuth integration%{link_end}' + 'ImportProjects|To enable importing projects from %{provider}, as administrator you need to configure %{link_start}OAuth integration%{link_end}' else - 'ImportProjects|To enable importing projects from Bitbucket, ask your GitLab administrator to configure %{link_start}OAuth integration%{link_end}' + 'ImportProjects|To enable importing projects from %{provider}, ask your GitLab administrator to configure %{link_start}OAuth integration%{link_end}' end - s_(str).html_safe % { link_start: link_start, link_end: '</a>'.html_safe } + link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_url } + s_(str).html_safe % { provider: provider, link_start: link_start, link_end: '</a>'.html_safe } end - private - def tab_ability_map { cycle_analytics: :read_cycle_analytics, diff --git a/app/helpers/routing/pseudonymization_helper.rb b/app/helpers/routing/pseudonymization_helper.rb index fd9907edc37..f1fafd563ce 100644 --- a/app/helpers/routing/pseudonymization_helper.rb +++ b/app/helpers/routing/pseudonymization_helper.rb @@ -15,7 +15,7 @@ module Routing end def mask_params - return default_root_url + @request.original_fullpath unless has_maskable_params? + return @request.original_url unless has_maskable_params? masked_params = @request.path_parameters.to_h do |key, value| case key @@ -66,10 +66,6 @@ module Routing query_string_hash end - - def default_root_url - Gitlab::Routing.url_helpers.root_url(only_path: false) - end end def masked_page_url(group:, project:) diff --git a/app/helpers/sessions_helper.rb b/app/helpers/sessions_helper.rb index e9466a9e97e..f0389000eb3 100644 --- a/app/helpers/sessions_helper.rb +++ b/app/helpers/sessions_helper.rb @@ -5,7 +5,7 @@ module SessionsHelper def recently_confirmed_com? strong_memoize(:recently_confirmed_com) do - ::Gitlab.dev_env_or_com? && + ::Gitlab.com? && !!flash[:notice]&.include?(t(:confirmed, scope: [:devise, :confirmations])) end end diff --git a/app/helpers/sorting_helper.rb b/app/helpers/sorting_helper.rb index fb30e8ca059..4db14d5cc4d 100644 --- a/app/helpers/sorting_helper.rb +++ b/app/helpers/sorting_helper.rb @@ -328,6 +328,16 @@ module SortingHelper sort_direction_button(url, reverse_sort, sort_value) end + + def admin_users_sort_options(path_params) + users_sort_options_hash.map do |value, text| + { + value: value, + text: text, + href: admin_users_path(sort: value, **path_params) + } + end + end end SortingHelper.prepend_mod_with('SortingHelper') diff --git a/app/helpers/storage_helper.rb b/app/helpers/storage_helper.rb index 34ba66db444..a075ccc38f5 100644 --- a/app/helpers/storage_helper.rb +++ b/app/helpers/storage_helper.rb @@ -25,16 +25,17 @@ module StorageHelper end def storage_enforcement_banner_info(namespace) + return unless can?(current_user, :admin_namespace, namespace) return if namespace.paid? return unless namespace.storage_enforcement_date && namespace.storage_enforcement_date >= Date.today return if user_dismissed_storage_enforcement_banner?(namespace) { text: html_escape_once(s_("UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. " \ - "View and manage your usage in %{strong_start}Group Settings > Usage quotas%{strong_end}.")).html_safe % - { storage_enforcement_date: namespace.storage_enforcement_date, strong_start: "<strong>".html_safe, strong_end: "</strong>".html_safe }, + "View and manage your usage in %{strong_start}%{namespace_type} settings > Usage quotas%{strong_end}.")).html_safe % + { storage_enforcement_date: namespace.storage_enforcement_date, strong_start: "<strong>".html_safe, strong_end: "</strong>".html_safe, namespace_type: namespace.type }, variant: 'warning', - callouts_path: group_callouts_path, + callouts_path: namespace.user_namespace? ? callouts_path : group_callouts_path, callouts_feature_name: storage_enforcement_banner_user_callouts_feature_name(namespace), learn_more_link: link_to(_('Learn more.'), help_page_path('/'), rel: 'noopener noreferrer', target: '_blank') # TBD: https://gitlab.com/gitlab-org/gitlab/-/issues/350632 } @@ -52,13 +53,17 @@ module StorageHelper return :first if days_to_enforcement_date > 30 return :second if days_to_enforcement_date > 15 && days_to_enforcement_date <= 30 return :third if days_to_enforcement_date > 7 && days_to_enforcement_date <= 15 - return :fourth if days_to_enforcement_date > 0 && days_to_enforcement_date <= 7 + return :fourth if days_to_enforcement_date >= 0 && days_to_enforcement_date <= 7 end def user_dismissed_storage_enforcement_banner?(namespace) return false unless current_user - current_user.dismissed_callout_for_group?(feature_name: storage_enforcement_banner_user_callouts_feature_name(namespace), - group: namespace) + if namespace.user_namespace? + current_user.dismissed_callout?(feature_name: storage_enforcement_banner_user_callouts_feature_name(namespace)) + else + current_user.dismissed_callout_for_group?(feature_name: storage_enforcement_banner_user_callouts_feature_name(namespace), + group: namespace) + end end end diff --git a/app/helpers/submodule_helper.rb b/app/helpers/submodule_helper.rb index f1e0be3a622..d3af6a00181 100644 --- a/app/helpers/submodule_helper.rb +++ b/app/helpers/submodule_helper.rb @@ -32,7 +32,7 @@ module SubmoduleHelper namespace.sub!(%r{\A/}, '') project.rstrip! - project.sub!(/\.git\z/, '') + project.delete_suffix!('.git') if self_url?(url, namespace, project) [ diff --git a/app/helpers/todos_helper.rb b/app/helpers/todos_helper.rb index 79767ca76b7..60bf79f3114 100644 --- a/app/helpers/todos_helper.rb +++ b/app/helpers/todos_helper.rb @@ -18,7 +18,7 @@ module TodosHelper when Todo::ASSIGNED then todo.self_added? ? 'assigned' : 'assigned you' when Todo::REVIEW_REQUESTED then 'requested a review of' when Todo::MENTIONED then "mentioned #{todo_action_subject(todo)} on" - when Todo::BUILD_FAILED then 'The build failed for' + when Todo::BUILD_FAILED then 'The pipeline failed in' when Todo::MARKED then 'added a todo for' when Todo::APPROVAL_REQUIRED then "set #{todo_action_subject(todo)} as an approver for" when Todo::UNMERGEABLE then 'Could not merge' diff --git a/app/helpers/tree_helper.rb b/app/helpers/tree_helper.rb index 23a9601aed7..2fef4ae98a9 100644 --- a/app/helpers/tree_helper.rb +++ b/app/helpers/tree_helper.rb @@ -203,9 +203,11 @@ module TreeHelper show_edit_button: show_edit_button?(options), show_web_ide_button: show_web_ide_button?, show_gitpod_button: show_gitpod_button?, + show_pipeline_editor_button: show_pipeline_editor_button?(@project, @path), web_ide_url: web_ide_url, edit_url: edit_url(options), + pipeline_editor_url: project_ci_pipeline_editor_path(@project, branch_name: @ref), gitpod_url: gitpod_url, user_preferences_gitpod_path: profile_preferences_path(anchor: 'user_gitpod_enabled'), diff --git a/app/helpers/users/callouts_helper.rb b/app/helpers/users/callouts_helper.rb index 32b0d7b3fe3..87c8bf5cb28 100644 --- a/app/helpers/users/callouts_helper.rb +++ b/app/helpers/users/callouts_helper.rb @@ -10,6 +10,7 @@ module Users REGISTRATION_ENABLED_CALLOUT = 'registration_enabled_callout' UNFINISHED_TAG_CLEANUP_CALLOUT = 'unfinished_tag_cleanup_callout' SECURITY_NEWSLETTER_CALLOUT = 'security_newsletter_callout' + REGISTRATION_ENABLED_CALLOUT_ALLOWED_CONTROLLER_PATHS = [/^root/, /^dashboard\S*/, /^admin\S*/].freeze def show_gke_cluster_integration_callout?(project) active_nav_link?(controller: sidebar_operations_paths) && @@ -47,7 +48,8 @@ module Users !Gitlab.com? && current_user&.admin? && signup_enabled? && - !user_dismissed?(REGISTRATION_ENABLED_CALLOUT) + !user_dismissed?(REGISTRATION_ENABLED_CALLOUT) && + REGISTRATION_ENABLED_CALLOUT_ALLOWED_CONTROLLER_PATHS.any? { |path| controller.controller_path.match?(path) } end def dismiss_two_factor_auth_recovery_settings_check diff --git a/app/helpers/web_ide_button_helper.rb b/app/helpers/web_ide_button_helper.rb index 6c73d365e8e..9ec22a659d3 100644 --- a/app/helpers/web_ide_button_helper.rb +++ b/app/helpers/web_ide_button_helper.rb @@ -29,6 +29,10 @@ module WebIdeButtonHelper show_web_ide_button? && Gitlab::CurrentSettings.gitpod_enabled end + def show_pipeline_editor_button?(project, path) + can_view_pipeline_editor?(project) && path == project.ci_config_path_or_default + end + def can_push_code? current_user&.can?(:push_code, @project) end diff --git a/app/helpers/whats_new_helper.rb b/app/helpers/whats_new_helper.rb index ccccfcb930b..bbf56c51c6d 100644 --- a/app/helpers/whats_new_helper.rb +++ b/app/helpers/whats_new_helper.rb @@ -10,7 +10,7 @@ module WhatsNewHelper end def display_whats_new? - (Gitlab.dev_env_org_or_com? || user_signed_in?) && + (Gitlab.org_or_com? || user_signed_in?) && !Gitlab::CurrentSettings.current_application_settings.whats_new_variant_disabled? end |