diff options
Diffstat (limited to 'app/helpers')
44 files changed, 272 insertions, 133 deletions
diff --git a/app/helpers/appearances_helper.rb b/app/helpers/appearances_helper.rb index cb43d911a2f..6dbd0f7bd7b 100644 --- a/app/helpers/appearances_helper.rb +++ b/app/helpers/appearances_helper.rb @@ -35,23 +35,21 @@ module AppearancesHelper end end - def brand_header_logo + def brand_header_logo(options = {}) + add_gitlab_white_text = options[:add_gitlab_white_text] || false + add_gitlab_black_text = options[:add_gitlab_black_text] || false + 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 + elsif add_gitlab_white_text + render partial: 'shared/logo_with_white_text', formats: :svg + elsif add_gitlab_black_text + render partial: 'shared/logo_with_black_text', formats: :svg else render partial: 'shared/logo', formats: :svg end end - # Skip the 'GitLab' type logo when custom brand logo is set - def brand_header_logo_type - unless current_appearance&.header_logo? - render partial: 'shared/logo_type', formats: :svg - end - end - def header_message return unless current_appearance&.show_header? diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index feeedb0a501..8cdfc267693 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -21,7 +21,7 @@ module ApplicationHelper def dispensable_render(...) render(...) rescue StandardError => error - if Feature.enabled?(:dispensable_render, default_enabled: :yaml) + if Feature.enabled?(:dispensable_render) Gitlab::ErrorTracking.track_and_raise_for_dev_exception(error) nil else @@ -32,7 +32,7 @@ module ApplicationHelper def dispensable_render_if_exists(...) render_if_exists(...) rescue StandardError => error - if Feature.enabled?(:dispensable_render, default_enabled: :yaml) + if Feature.enabled?(:dispensable_render) Gitlab::ErrorTracking.track_and_raise_for_dev_exception(error) nil else diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb index 57e08eeb4f4..9023cca18dc 100644 --- a/app/helpers/application_settings_helper.rb +++ b/app/helpers/application_settings_helper.rb @@ -97,24 +97,18 @@ module ApplicationSettingsHelper end end - def oauth_providers_checkboxes + def oauth_providers_checkboxes(form) button_based_providers.map do |source| - disabled = @application_setting.disabled_oauth_sign_in_sources.include?(source.to_s) + checked = !@application_setting.disabled_oauth_sign_in_sources.include?(source.to_s) name = Gitlab::Auth::OAuth::Provider.label_for(source) - checkbox_name = 'application_setting[enabled_oauth_sign_in_sources][]' - checkbox_id = "application_setting_enabled_oauth_sign_in_sources_#{name.parameterize(separator: '_')}" - - content_tag :div, class: 'form-check' do - check_box_tag( - checkbox_name, - source, - !disabled, - autocomplete: 'off', - id: checkbox_id, - class: 'form-check-input' - ) + - label_tag(checkbox_id, name, class: 'form-check-label') - end + + form.gitlab_ui_checkbox_component( + :enabled_oauth_sign_in_sources, + name, + checkbox_options: { checked: checked, multiple: true, autocomplete: 'off' }, + checked_value: source, + unchecked_value: nil + ) end end @@ -278,6 +272,7 @@ module ApplicationSettingsHelper :invisible_captcha_enabled, :max_artifacts_size, :max_attachment_size, + :max_export_size, :max_import_size, :max_pages_size, :max_yaml_size_bytes, @@ -412,6 +407,8 @@ module ApplicationSettingsHelper :container_registry_import_max_retries, :container_registry_import_start_max_retries, :container_registry_import_max_step_duration, + :container_registry_pre_import_timeout, + :container_registry_import_timeout, :container_registry_import_target_plan, :container_registry_import_created_before, :keep_latest_artifact, @@ -431,7 +428,8 @@ module ApplicationSettingsHelper :users_get_by_id_limit_allowlist_raw, :runner_token_expiration_interval, :group_runner_token_expiration_interval, - :project_runner_token_expiration_interval + :project_runner_token_expiration_interval, + :pipeline_limit_per_project_user_sha ].tap do |settings| settings << :deactivate_dormant_users unless Gitlab.com? end @@ -468,7 +466,7 @@ module ApplicationSettingsHelper def instance_clusters_enabled? clusterable = Clusters::Instance.new - Feature.enabled?(:certificate_based_clusters, clusterable, default_enabled: :yaml, type: :ops) && + clusterable.certificate_based_clusters_enabled? && can?(current_user, :read_cluster, clusterable) end diff --git a/app/helpers/auth_helper.rb b/app/helpers/auth_helper.rb index 6ac4a12bcd5..07152133402 100644 --- a/app/helpers/auth_helper.rb +++ b/app/helpers/auth_helper.rb @@ -91,7 +91,9 @@ module AuthHelper end def saml_providers - auth_providers.select { |provider| auth_strategy_class(provider) == 'OmniAuth::Strategies::SAML' } + auth_providers.select do |provider| + provider == :saml || auth_strategy_class(provider) == 'OmniAuth::Strategies::SAML' + end end def auth_strategy_class(provider) diff --git a/app/helpers/badges_helper.rb b/app/helpers/badges_helper.rb index a03f7f4097a..26ebe8a6470 100644 --- a/app/helpers/badges_helper.rb +++ b/app/helpers/badges_helper.rb @@ -69,6 +69,7 @@ module BadgesHelper icon_only = options[:icon_only] variant_class = VARIANT_CLASSES[options.fetch(:variant, :muted)] size_class = SIZE_CLASSES[options.fetch(:size, :md)] + icon_classes = GL_ICON_CLASSES.dup << options.fetch(:icon_classes, nil) html_options = html_options.merge( class: [ @@ -85,7 +86,6 @@ module BadgesHelper end if options[:icon] - icon_classes = GL_ICON_CLASSES.dup icon_classes << "gl-mr-2" unless icon_only icon = sprite_icon(options[:icon], css_class: icon_classes.join(' ')) diff --git a/app/helpers/boards_helper.rb b/app/helpers/boards_helper.rb index f849f36bf84..f98e70e41d8 100644 --- a/app/helpers/boards_helper.rb +++ b/app/helpers/boards_helper.rb @@ -25,7 +25,6 @@ module BoardsHelper labels_manage_path: labels_manage_path, releases_fetch_path: releases_fetch_path, board_type: board.to_type, - has_scope: board.scoped?.to_s, has_missing_boards: has_missing_boards?.to_s, multiple_boards_available: multiple_boards_available?.to_s, board_base_url: board_base_url diff --git a/app/helpers/broadcast_messages_helper.rb b/app/helpers/broadcast_messages_helper.rb index b138e9aeb0c..10cfa97030d 100644 --- a/app/helpers/broadcast_messages_helper.rb +++ b/app/helpers/broadcast_messages_helper.rb @@ -73,7 +73,7 @@ module BroadcastMessagesHelper private def current_user_access_level_for_project_or_group - return if Feature.disabled?(:role_targeted_broadcast_messages, default_enabled: :yaml) + return if Feature.disabled?(:role_targeted_broadcast_messages) return unless current_user.present? strong_memoize(:current_user_access_level_for_project_or_group) do diff --git a/app/helpers/ci/builds_helper.rb b/app/helpers/ci/builds_helper.rb index bfdb830f2c3..b4a2cf7bb1e 100644 --- a/app/helpers/ci/builds_helper.rb +++ b/app/helpers/ci/builds_helper.rb @@ -36,5 +36,15 @@ module Ci description: project_job_url(@project, @build) } end + + def prepare_failed_jobs_summary_data(failed_builds) + failed_builds.map do |build| + { + id: build.id, + failure: build.present.callout_failure_message, + failure_summary: build_summary(build) + } + end.to_json + end end end diff --git a/app/helpers/ci/pipeline_editor_helper.rb b/app/helpers/ci/pipeline_editor_helper.rb index 18557afcb99..da773e3e8a8 100644 --- a/app/helpers/ci/pipeline_editor_helper.rb +++ b/app/helpers/ci/pipeline_editor_helper.rb @@ -21,6 +21,7 @@ module Ci "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, + "includes-help-page-path" => help_page_path('ci/yaml/includes'), "lint-help-page-path" => help_page_path('ci/lint', anchor: 'check-cicd-syntax'), "lint-unavailable-help-page-path" => help_page_path('ci/pipeline_editor/index', anchor: 'configuration-validation-currently-not-available-message'), "needs-help-page-path" => help_page_path('ci/yaml/index', anchor: 'needs'), diff --git a/app/helpers/ci/pipelines_helper.rb b/app/helpers/ci/pipelines_helper.rb index 70d2a4fafd1..7722677e503 100644 --- a/app/helpers/ci/pipelines_helper.rb +++ b/app/helpers/ci/pipelines_helper.rb @@ -42,7 +42,7 @@ module Ci { name: 'Django', logo: image_path('illustrations/third-party-logos/ci_cd-template-logos/django.svg') }, { name: 'Docker', logo: image_path('illustrations/third-party-logos/ci_cd-template-logos/docker.svg') }, { name: 'Elixir', logo: image_path('illustrations/third-party-logos/ci_cd-template-logos/elixir.svg') }, - { name: 'iOS-Fastlane', logo: image_path('illustrations/third-party-logos/ci_cd-template-logos/fastlane.svg') }, + { name: 'iOS-Fastlane', logo: image_path('illustrations/third-party-logos/ci_cd-template-logos/fastlane.svg'), title: 'iOS with Fastlane' }, { name: 'Flutter', logo: image_path('illustrations/third-party-logos/ci_cd-template-logos/flutter.svg') }, { name: 'Go', logo: image_path('illustrations/third-party-logos/ci_cd-template-logos/go_logo.svg') }, { name: 'Gradle', logo: image_path('illustrations/third-party-logos/ci_cd-template-logos/gradle.svg') }, @@ -51,6 +51,7 @@ module Ci { name: 'Julia', logo: image_path('illustrations/third-party-logos/ci_cd-template-logos/julia.svg') }, { name: 'Laravel', logo: image_path('illustrations/third-party-logos/ci_cd-template-logos/laravel.svg') }, { name: 'LaTeX', logo: image_path('illustrations/third-party-logos/ci_cd-template-logos/latex.svg') }, + { name: 'MATLAB', logo: image_path('illustrations/third-party-logos/ci_cd-template-logos/matlab.svg') }, { name: 'Maven', logo: image_path('illustrations/third-party-logos/ci_cd-template-logos/maven.svg') }, { name: 'Mono', logo: image_path('illustrations/third-party-logos/ci_cd-template-logos/mono.svg') }, { name: 'Nodejs', logo: image_path('illustrations/third-party-logos/ci_cd-template-logos/node_js.svg') }, @@ -109,6 +110,7 @@ module Ci experiment(:ios_specific_templates, actor: current_user, project: project, sticky_to: project) do |e| e.candidate do data[:registration_token] = project.runners_token if can?(current_user, :register_project_runners, project) + data[:ios_runners_available] = (project.shared_runners_available? && Gitlab.com?).to_s end end diff --git a/app/helpers/ci/runners_helper.rb b/app/helpers/ci/runners_helper.rb index 0e8b6fa6d25..6366ca0dfb1 100644 --- a/app/helpers/ci/runners_helper.rb +++ b/app/helpers/ci/runners_helper.rb @@ -17,7 +17,7 @@ module Ci title = s_("Runners|Runner is online; last contact was %{runner_contact} ago") % { runner_contact: time_ago_in_words(contacted_at) } icon = 'status-active' span_class = 'gl-text-green-500' - when :not_connected, :never_contacted + when :never_contacted title = s_("Runners|Runner has never contacted this instance") icon = 'warning-solid' when :offline @@ -72,11 +72,11 @@ module Ci def group_shared_runners_settings_data(group) { update_path: api_v4_groups_path(id: group.id), - shared_runners_availability: group.shared_runners_setting, - parent_shared_runners_availability: group.parent&.shared_runners_setting, - runner_enabled: Namespace::SR_ENABLED, - runner_disabled: Namespace::SR_DISABLED_AND_UNOVERRIDABLE, - runner_allow_override: Namespace::SR_DISABLED_WITH_OVERRIDE + shared_runners_setting: group.shared_runners_setting, + parent_shared_runners_setting: group.parent&.shared_runners_setting, + runner_enabled_value: Namespace::SR_ENABLED, + runner_disabled_value: Namespace::SR_DISABLED_AND_UNOVERRIDABLE, + runner_allow_override_value: Namespace::SR_DISABLED_WITH_OVERRIDE } end diff --git a/app/helpers/ci/secure_files_helper.rb b/app/helpers/ci/secure_files_helper.rb new file mode 100644 index 00000000000..30b2e12ac3b --- /dev/null +++ b/app/helpers/ci/secure_files_helper.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true +module Ci + module SecureFilesHelper + def show_secure_files_setting(project, user) + return false if user.nil? + + Feature.enabled?(:ci_secure_files, project) && user.can?(:read_secure_files, project) + end + end +end diff --git a/app/helpers/clusters_helper.rb b/app/helpers/clusters_helper.rb index fe057fb3412..8449bccd285 100644 --- a/app/helpers/clusters_helper.rb +++ b/app/helpers/clusters_helper.rb @@ -17,17 +17,17 @@ module ClustersHelper 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, add_cluster_path: clusterable.connect_path, new_cluster_docs_path: clusterable.new_cluster_docs_path, can_add_cluster: clusterable.can_add_cluster?.to_s, 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, + certificate_based_clusters_enabled: clusterable.certificate_based_clusters_enabled?.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 + gitlab_version: Gitlab.version_info, + kas_version: Gitlab::Kas.version_info } end @@ -39,13 +39,7 @@ module ClustersHelper base_domain: cluster.base_domain, application_ingress_external_ip: cluster.application_ingress_external_ip, auto_devops_help_path: help_page_path('topics/autodevops/index'), - external_endpoint_help_path: help_page_path('user/project/clusters/index.md', anchor: 'base-domain') - } - end - - def js_cluster_new - { - cluster_connect_help_path: help_page_path('user/project/clusters/add_remove_clusters', anchor: 'add-existing-cluster') + external_endpoint_help_path: help_page_path('user/project/clusters/gitlab_managed_clusters.md', anchor: 'base-domain') } end diff --git a/app/helpers/container_registry_helper.rb b/app/helpers/container_registry_helper.rb index 255b8183164..52ef276c097 100644 --- a/app/helpers/container_registry_helper.rb +++ b/app/helpers/container_registry_helper.rb @@ -1,10 +1,6 @@ # frozen_string_literal: true module ContainerRegistryHelper - def container_registry_expiration_policies_throttling? - Feature.enabled?(:container_registry_expiration_policies_throttling, default_enabled: :yaml) - end - def container_repository_gid_prefix "gid://#{GlobalID.app}/#{ContainerRepository.name}/" end diff --git a/app/helpers/emails_helper.rb b/app/helpers/emails_helper.rb index 79b04ae0e2b..59731dc2f6f 100644 --- a/app/helpers/emails_helper.rb +++ b/app/helpers/emails_helper.rb @@ -69,8 +69,8 @@ module EmailsHelper ) else image_tag( - image_url('mailers/gitlab_header_logo.gif'), - size: '55x50', + image_url('mailers/gitlab_logo.png'), + size: '55x55', alt: 'GitLab' ) end diff --git a/app/helpers/groups/group_members_helper.rb b/app/helpers/groups/group_members_helper.rb index 80ab303357b..ca61c4da41c 100644 --- a/app/helpers/groups/group_members_helper.rb +++ b/app/helpers/groups/group_members_helper.rb @@ -53,7 +53,7 @@ module Groups::GroupMembersHelper end def group_group_links_list_data(group, include_relations, search) - if ::Feature.enabled?(:group_member_inherited_group, group, default_enabled: :yaml) + if ::Feature.enabled?(:group_member_inherited_group, group) group_links = group_group_links(group, include_relations) group_links = group_links.search(search) if search else diff --git a/app/helpers/instance_configuration_helper.rb b/app/helpers/instance_configuration_helper.rb index f695be32743..b06e3ff2904 100644 --- a/app/helpers/instance_configuration_helper.rb +++ b/app/helpers/instance_configuration_helper.rb @@ -17,4 +17,8 @@ module InstanceConfigurationHelper number_to_human_size(v, strip_insignificant_zeros: true, significant: false) end end + + def instance_configuration_disabled_cell_html(value) + instance_configuration_cell_html(value == 0 ? nil : value) + end end diff --git a/app/helpers/integrations_helper.rb b/app/helpers/integrations_helper.rb index b960ed46ba9..862938ac961 100644 --- a/app/helpers/integrations_helper.rb +++ b/app/helpers/integrations_helper.rb @@ -112,6 +112,7 @@ module IntegrationsHelper enable_comments: integration.comment_on_event_enabled.to_s, comment_detail: integration.comment_detail, learn_more_path: integrations_help_page_path, + about_pricing_url: Gitlab::Saas.about_pricing_url, trigger_events: trigger_events_for_integration(integration), sections: integration.sections.to_json, fields: fields_for_integration(integration), diff --git a/app/helpers/invite_members_helper.rb b/app/helpers/invite_members_helper.rb index a682d2712be..e46270ab819 100644 --- a/app/helpers/invite_members_helper.rb +++ b/app/helpers/invite_members_helper.rb @@ -20,30 +20,17 @@ module InviteMembersHelper end end - def group_select_data(group) - # This should only be used for groups to load the invite group modal. - # For instance the invite groups modal should not call this from a project scope - # this is only to be called in scope of a group context as noted in this thread - # https://gitlab.com/gitlab-org/gitlab/-/merge_requests/79036#note_821465513 - # the group sharing in projects disabling is explained there as well - if group.root_ancestor.namespace_settings.prevent_sharing_groups_outside_hierarchy - { groups_filter: 'descendant_groups', parent_id: group.root_ancestor.id } - else - {} - end - end - def common_invite_group_modal_data(source, member_class, is_project) { id: source.id, - root_id: source.root_ancestor&.id, + root_id: source.root_ancestor.id, name: source.name, default_access_level: Gitlab::Access::GUEST, invalid_groups: source.related_group_ids, help_link: help_page_url('user/permissions'), is_project: is_project, access_levels: member_class.access_level_roles.to_json - } + }.merge(group_select_data(source)) end # Overridden in EE @@ -68,6 +55,14 @@ module InviteMembersHelper private + def group_select_data(source) + if source.root_ancestor.prevent_sharing_groups_outside_hierarchy + { groups_filter: 'descendant_groups', parent_id: source.root_ancestor.id } + else + {} + end + end + # Overridden in EE def users_filter_data(group) {} diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb index 98eca3785e7..486d5bb3866 100644 --- a/app/helpers/issuables_helper.rb +++ b/app/helpers/issuables_helper.rb @@ -13,6 +13,8 @@ module IssuablesHelper end def sidebar_gutter_collapsed_class + return "right-sidebar-expanded" if moved_mr_sidebar_enabled? + "right-sidebar-#{sidebar_gutter_collapsed? ? 'collapsed' : 'expanded'}" end @@ -236,6 +238,7 @@ module IssuablesHelper markdownPreviewPath: preview_markdown_path(parent, target_type: issuable.model_name, target_id: issuable.iid), markdownDocsPath: help_page_path('user/markdown'), lockVersion: issuable.lock_version, + state: issuable.state, issuableTemplateNamesPath: template_names_path(parent, issuable), initialTitleHtml: markdown_field(issuable, :title), initialTitleText: issuable.title, @@ -341,14 +344,20 @@ module IssuablesHelper end def state_name_with_icon(issuable) - if issuable.is_a?(MergeRequest) && issuable.merged? - [_("Merged"), "git-merge"] - elsif issuable.is_a?(MergeRequest) && issuable.closed? - [_("Closed"), "close"] - elsif issuable.closed? - [_("Closed"), "mobile-issue-close"] + if issuable.is_a?(MergeRequest) + if issuable.open? + [_("Open"), "merge-request-open"] + elsif issuable.merged? + [_("Merged"), "merge"] + else + [_("Closed"), "merge-request-close"] + end else - [_("Open"), "issue-open-m"] + if issuable.open? + [_("Open"), "issues"] + else + [_("Closed"), "issue-closed"] + end end end diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb index c8c9ea32184..04de77dd484 100644 --- a/app/helpers/issues_helper.rb +++ b/app/helpers/issues_helper.rb @@ -28,16 +28,18 @@ module IssuesHelper end def status_box_class(item) + updated_mr_header_enabled = Feature.enabled?(:updated_mr_header, @project) + if item.try(:expired?) 'status-box-expired' elsif item.try(:merged?) - 'status-box-mr-merged' + updated_mr_header_enabled ? 'badge-info' : 'status-box-mr-merged' elsif item.closed? - 'status-box-mr-closed' + item.is_a?(MergeRequest) && updated_mr_header_enabled ? 'badge-danger' : 'status-box-mr-closed' elsif item.try(:upcoming?) 'status-box-upcoming' else - 'status-box-open' + item.is_a?(MergeRequest) && updated_mr_header_enabled ? 'badge-success' : 'status-box-open' end end @@ -63,7 +65,7 @@ module IssuesHelper end def issue_hidden?(issue) - Feature.enabled?(:ban_user_feature_flag, default_enabled: :yaml) && issue.hidden? + Feature.enabled?(:ban_user_feature_flag) && issue.hidden? end def hidden_issue_icon(issue) @@ -152,7 +154,7 @@ module IssuesHelper end def issue_closed_text(issue, current_user) - link = issue_closed_link(issue, current_user, css_class: 'text-white text-underline') + link = issue_closed_link(issue, current_user, css_class: 'text-underline gl-reset-color!') if link s_('IssuableStatus|Closed (%{link})').html_safe % { link: link } @@ -202,6 +204,8 @@ module IssuesHelper initial_sort: current_user&.user_preference&.issues_sort, is_anonymous_search_disabled: Feature.enabled?(:disable_anonymous_search, type: :ops).to_s, is_issue_repositioning_disabled: issue_repositioning_disabled?.to_s, + is_public_visibility_restricted: + Gitlab::CurrentSettings.restricted_visibility_levels.include?(Gitlab::VisibilityLevel::PUBLIC).to_s, is_signed_in: current_user.present?.to_s, jira_integration_path: help_page_url('integration/jira/issues', anchor: 'view-jira-issues'), rss_path: url_for(safe_params.merge(rss_url_options)), diff --git a/app/helpers/jira_connect_helper.rb b/app/helpers/jira_connect_helper.rb index 67b85b26f9e..30f29e002b8 100644 --- a/app/helpers/jira_connect_helper.rb +++ b/app/helpers/jira_connect_helper.rb @@ -7,7 +7,8 @@ module JiraConnectHelper { groups_path: api_v4_groups_path(params: { min_access_level: Gitlab::Access::MAINTAINER, skip_groups: skip_groups }), subscriptions: subscriptions.map { |s| serialize_subscription(s) }.to_json, - subscriptions_path: jira_connect_subscriptions_path, + add_subscriptions_path: jira_connect_subscriptions_path, + subscriptions_path: jira_connect_subscriptions_path(format: :json), 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, oauth_metadata: Feature.enabled?(:jira_connect_oauth, current_user) ? jira_connect_oauth_data.to_json : nil diff --git a/app/helpers/lazy_image_tag_helper.rb b/app/helpers/lazy_image_tag_helper.rb index d0bdaaae5f8..10d603ef5d3 100644 --- a/app/helpers/lazy_image_tag_helper.rb +++ b/app/helpers/lazy_image_tag_helper.rb @@ -8,8 +8,11 @@ module LazyImageTagHelper end # Override the default ActionView `image_tag` helper to support lazy-loading + # accept :auto_dark boolean to enable automatic dark variant of the image + # (see: https://gitlab.com/gitlab-org/gitlab-ui/-/merge_requests/2698) + # accept :dark_variant path to be used as a source when dark mode is enabled def image_tag(source, options = {}) - source = options[:dark_variant] if options[:dark_variant] && user_application_dark_mode? + source, options = prepare_dark_variant(source, options) options = options.symbolize_keys unless options.delete(:lazy) == false @@ -29,4 +32,25 @@ module LazyImageTagHelper # Required for Banzai::Filter::ImageLazyLoadFilter module_function :placeholder_image # rubocop: disable Style/AccessModifierDeclarations + + private + + def prepare_dark_variant(source, options) + dark_variant = options.delete(:dark_variant) + auto_dark = options.delete(:auto_dark) + + if dark_variant && auto_dark + raise ArgumentError, "dark_variant and auto_dark are mutually exclusive" + end + + if (auto_dark || dark_variant) && user_application_dark_mode? + if auto_dark + options[:class] = 'gl-dark-invert-keep-hue' + elsif dark_variant + source = dark_variant + end + end + + [source, options] + end end diff --git a/app/helpers/learn_gitlab_helper.rb b/app/helpers/learn_gitlab_helper.rb index 60f3b12d736..890f7f099df 100644 --- a/app/helpers/learn_gitlab_helper.rb +++ b/app/helpers/learn_gitlab_helper.rb @@ -34,7 +34,8 @@ module LearnGitlabHelper action, url: url, completed: attributes[OnboardingProgress.column_name(action)].present?, - svg: image_path("learn_gitlab/#{action}.svg") + svg: image_path("learn_gitlab/#{action}.svg"), + enabled: true ] end end diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb index 2d93813d5ee..e1c9e7d3896 100644 --- a/app/helpers/merge_requests_helper.rb +++ b/app/helpers/merge_requests_helper.rb @@ -156,7 +156,7 @@ module MergeRequestsHelper total: total_count } - if Feature.enabled?(:mr_attention_requests, default_enabled: :yaml) + if current_user&.mr_attention_requests_enabled? attention_requested_count = attention_requested_merge_requests_count counts[:attention_requested_count] = attention_requested_count @@ -206,6 +206,19 @@ module MergeRequestsHelper api_v4_projects_merge_requests_award_emoji_path(id: merge_request.project.id, merge_request_iid: merge_request.iid) end + def how_merge_modal_data(merge_request) + { + is_fork: merge_request.for_fork?.to_s, + can_merge: merge_request.can_be_merged_by?(current_user).to_s, + source_branch: merge_request.source_branch, + source_project_path: merge_request.source_project&.path, + source_project_full_path: merge_request.source_project&.full_path, + source_project_default_url: merge_request.source_project && default_url_to_repo(merge_request.source_project), + target_branch: merge_request.target_branch, + reviewing_docs_path: help_page_path('user/project/merge_requests/reviews/index.md', anchor: "checkout-merge-requests-locally-through-the-head-ref") + } + end + private def review_requested_merge_requests_count @@ -219,6 +232,34 @@ module MergeRequestsHelper def default_suggestion_commit_message @project.suggestion_commit_message.presence || Gitlab::Suggestions::CommitMessage::DEFAULT_SUGGESTION_COMMIT_MESSAGE end + + def merge_request_source_branch(merge_request) + branch = if merge_request.for_fork? + "#{merge_request.source_project_path}:#{merge_request.source_branch}" + else + merge_request.source_branch + end + + branch_path = if merge_request.source_project + project_tree_path(merge_request.source_project, merge_request.source_branch) + else + '' + end + + link_to branch, branch_path, title: branch, class: 'gl-link gl-font-monospace gl-bg-blue-50 gl-rounded-base gl-font-sm gl-px-2 gl-display-inline-block gl-text-truncate gl-max-w-26 gl-mb-n2' + end + + def merge_request_header(project, merge_request) + link_to_author = link_to_member(project, merge_request.author, size: 24, extra_class: 'gl-font-weight-bold', avatar: false) + copy_button = clipboard_button(text: merge_request.source_branch, title: _('Copy branch name'), class: 'btn btn-default btn-sm gl-button btn-default-tertiary btn-icon gl-display-none! gl-md-display-inline-block! js-source-branch-copy') + target_branch = link_to merge_request.target_branch, project_tree_path(merge_request.target_project, merge_request.target_branch), title: merge_request.target_branch, class: 'gl-link gl-font-monospace gl-bg-blue-50 gl-rounded-base gl-font-sm gl-px-2 gl-display-inline-block gl-text-truncate gl-max-w-26 gl-mb-n2' + + _('%{author} requested to merge %{source_branch} %{copy_button} into %{target_branch} %{created_at}').html_safe % { author: link_to_author.html_safe, source_branch: merge_request_source_branch(merge_request).html_safe, copy_button: copy_button.html_safe, target_branch: target_branch.html_safe, created_at: time_ago_with_tooltip(merge_request.created_at, html_class: 'gl-display-inline-block').html_safe } + end + + def moved_mr_sidebar_enabled? + Feature.enabled?(:moved_mr_sidebar, @project) && defined?(@merge_request) + end end MergeRequestsHelper.prepend_mod_with('MergeRequestsHelper') diff --git a/app/helpers/namespaces_helper.rb b/app/helpers/namespaces_helper.rb index cf386ee398a..a50629b7996 100644 --- a/app/helpers/namespaces_helper.rb +++ b/app/helpers/namespaces_helper.rb @@ -88,11 +88,12 @@ module NamespacesHelper }.to_json end - def pipeline_usage_quota_app_data(namespace) + def pipeline_usage_app_data(namespace) { namespace_actual_plan_name: namespace.actual_plan_name, namespace_path: namespace.full_path, namespace_id: namespace.id, + user_namespace: namespace.user_namespace?.to_s, page_size: page_size } end diff --git a/app/helpers/nav_helper.rb b/app/helpers/nav_helper.rb index 1c4d294baa7..37cd491e19f 100644 --- a/app/helpers/nav_helper.rb +++ b/app/helpers/nav_helper.rb @@ -19,11 +19,13 @@ module NavHelper end def page_gutter_class + moved_sidebar_enabled = current_controller?('merge_requests') && moved_mr_sidebar_enabled? + if page_has_markdown? if cookies[:collapsed_gutter] == 'true' - %w[page-gutter right-sidebar-collapsed] + ["page-gutter", "#{'right-sidebar-collapsed' unless moved_sidebar_enabled}"] else - %w[page-gutter right-sidebar-expanded] + ["page-gutter", "#{'right-sidebar-expanded' unless moved_sidebar_enabled}"] end elsif current_path?('jobs#show') %w[page-gutter build-sidebar right-sidebar-expanded] @@ -56,7 +58,7 @@ module NavHelper end def admin_monitoring_nav_links - %w(system_info background_migrations background_jobs health_check requests_profiles) + %w(system_info background_migrations background_jobs health_check) end def admin_analytics_nav_links diff --git a/app/helpers/page_layout_helper.rb b/app/helpers/page_layout_helper.rb index fb74a52fcda..0c057a29bec 100644 --- a/app/helpers/page_layout_helper.rb +++ b/app/helpers/page_layout_helper.rb @@ -55,7 +55,7 @@ module PageLayoutHelper end def page_image - default = image_url('gitlab_logo.png') + default = image_url('twitter_card.jpg') subject = @project || @user || @group diff --git a/app/helpers/personal_access_tokens_helper.rb b/app/helpers/personal_access_tokens_helper.rb deleted file mode 100644 index 5cc8d21096f..00000000000 --- a/app/helpers/personal_access_tokens_helper.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true - -module PersonalAccessTokensHelper - def personal_access_token_expiration_enforced? - false - end -end diff --git a/app/helpers/profiles_helper.rb b/app/helpers/profiles_helper.rb index 0d514773891..20d0dd9b30c 100644 --- a/app/helpers/profiles_helper.rb +++ b/app/helpers/profiles_helper.rb @@ -53,13 +53,11 @@ module ProfilesHelper # Overridden in EE::ProfilesHelper#ssh_key_expiration_tooltip def ssh_key_expiration_tooltip(key) return key.errors.full_messages.join(', ') if key.errors.full_messages.any? - - s_('Profiles|Key usable beyond expiration date.') if key.expired? end # Overridden in EE::ProfilesHelper#ssh_key_expires_field_description def ssh_key_expires_field_description - s_('Profiles|Key can still be used after expiration.') + s_('Profiles|Key becomes invalid on this date.') end # Overridden in EE::ProfilesHelper#ssh_key_expiration_policy_enabled? diff --git a/app/helpers/projects/pipeline_helper.rb b/app/helpers/projects/pipeline_helper.rb index 185632a49b5..286026bc290 100644 --- a/app/helpers/projects/pipeline_helper.rb +++ b/app/helpers/projects/pipeline_helper.rb @@ -7,6 +7,7 @@ module Projects can_generate_codequality_reports: pipeline.can_generate_codequality_reports?.to_json, graphql_resource_etag: graphql_etag_pipeline_path(pipeline), metrics_path: namespace_project_ci_prometheus_metrics_histograms_path(namespace_id: project.namespace, project_id: project, format: :json), + pipeline_iid: pipeline.iid, pipeline_project_path: project.full_path } end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 21c7a54670c..c3f22dc7693 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -212,7 +212,7 @@ module ProjectsHelper end def no_password_message - push_pull_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('gitlab-basics/start-using-git', anchor: 'pull-and-push') } + push_pull_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('topics/git/terminology', anchor: 'pull-and-push') } clone_with_https_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('gitlab-basics/start-using-git', anchor: 'clone-with-https') } set_password_link_start = '<a href="%{url}">'.html_safe % { url: edit_profile_password_path } set_up_pat_link_start = '<a href="%{url}">'.html_safe % { url: profile_personal_access_tokens_path } @@ -379,7 +379,7 @@ module ProjectsHelper end def show_terraform_banner?(project) - Feature.enabled?(:show_terraform_banner, type: :ops, default_enabled: true) && project.repository_languages.with_programming_language('HCL').exists? && project.terraform_states.empty? + Feature.enabled?(:show_terraform_banner, type: :ops) && project.repository_languages.with_programming_language('HCL').exists? && project.terraform_states.empty? end def project_permissions_panel_data(project) @@ -614,6 +614,7 @@ module ProjectsHelper operationsAccessLevel: feature.operations_access_level, showDefaultAwardEmojis: project.show_default_award_emojis?, warnAboutPotentiallyUnwantedCharacters: project.warn_about_potentially_unwanted_characters?, + enforceAuthChecksOnUploads: project.enforce_auth_checks_on_uploads?, securityAndComplianceAccessLevel: project.security_and_compliance_access_level, containerRegistryAccessLevel: feature.container_registry_access_level } diff --git a/app/helpers/releases_helper.rb b/app/helpers/releases_helper.rb index 4fa61191ba5..a516ac85131 100644 --- a/app/helpers/releases_helper.rb +++ b/app/helpers/releases_helper.rb @@ -12,7 +12,7 @@ module ReleasesHelper image_path(IMAGE_PATH) end - def help_page(anchor: nil) + def releases_help_page_path(anchor: nil) help_page_path(DOCUMENTATION_PATH, anchor: anchor) end @@ -21,7 +21,7 @@ module ReleasesHelper project_id: @project.id, project_path: @project.full_path, illustration_path: illustration, - documentation_path: help_page + documentation_path: releases_help_page_path }.tap do |data| if can?(current_user, :create_release, @project) data[:new_release_path] = new_project_release_path(@project) @@ -78,9 +78,10 @@ module ReleasesHelper project_path: @project.full_path, markdown_preview_path: preview_markdown_path(@project), markdown_docs_path: help_page_path('user/markdown'), - release_assets_docs_path: help_page(anchor: 'release-assets'), + 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) + new_milestone_path: new_project_milestone_path(@project), + edit_release_docs_path: releases_help_page_path(anchor: 'edit-a-release') } end end diff --git a/app/helpers/routing/projects_helper.rb b/app/helpers/routing/projects_helper.rb index 859070d59ec..8c0bd9b1ecc 100644 --- a/app/helpers/routing/projects_helper.rb +++ b/app/helpers/routing/projects_helper.rb @@ -35,7 +35,15 @@ module Routing end def issue_url(entity, *args) - project_issue_url(entity.project, entity, *args) + if use_work_items_path?(entity) + work_item_url(entity, *args) + else + project_issue_url(entity.project, entity, *args) + end + end + + def work_item_url(entity, *args) + project_work_items_url(entity.project, entity.id, *args) end def merge_request_url(entity, *args) @@ -77,5 +85,11 @@ module Routing toggle_subscription_project_merge_request_path(entity.project, entity) end end + + private + + def use_work_items_path?(issue) + issue.issue_type == 'task' && issue.project.work_items_feature_flag_enabled? + end end end diff --git a/app/helpers/routing/pseudonymization_helper.rb b/app/helpers/routing/pseudonymization_helper.rb index 3e5d4ee21c0..eb4e5d1c01c 100644 --- a/app/helpers/routing/pseudonymization_helper.rb +++ b/app/helpers/routing/pseudonymization_helper.rb @@ -10,6 +10,8 @@ module Routing sortDesc state tab + glm_source + glm_content ].freeze def initialize(request_object, group, project) diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb index f8bfc74b344..69bea0abd88 100644 --- a/app/helpers/search_helper.rb +++ b/app/helpers/search_helper.rb @@ -374,8 +374,6 @@ module SearchHelper autocomplete: 'off' } - opts[:data]['runner-tags-endpoint'] = tag_list_admin_runners_path - if @project.present? opts[:data]['project-id'] = @project.id opts[:data]['labels-endpoint'] = project_labels_path(@project) @@ -445,7 +443,7 @@ module SearchHelper return false unless can?(current_user, :read_users_list) return true if @group - Feature.enabled?(:global_search_users_tab, current_user, type: :ops, default_enabled: :yaml) + Feature.enabled?(:global_search_users_tab, current_user, type: :ops) end def issuable_state_to_badge_class(issuable) @@ -479,7 +477,7 @@ module SearchHelper end def feature_flag_tab_enabled?(flag) - @group || Feature.enabled?(flag, current_user, type: :ops, default_enabled: true) + @group || Feature.enabled?(flag, current_user, type: :ops) end end diff --git a/app/helpers/sorting_helper.rb b/app/helpers/sorting_helper.rb index b4ad9db815d..43ec02b6537 100644 --- a/app/helpers/sorting_helper.rb +++ b/app/helpers/sorting_helper.rb @@ -250,6 +250,51 @@ module SortingHelper sort_options_hash[sort_value] end + def issuable_sort_options(viewing_issues, viewing_merge_requests) + 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_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) } + ] + + 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([relative_position_option]) if viewing_issues + + options.concat([title_option]) + end + + def due_date_option + { value: sort_value_due_date, text: sort_title_due_date, href: page_filter_path(sort: sort_value_due_date) } + end + + def popularity_option + { value: sort_value_popularity, text: sort_title_popularity, href: page_filter_path(sort: sort_value_popularity) } + end + + def label_priority_option + { value: sort_value_label_priority, text: sort_title_label_priority, href: page_filter_path(sort: sort_value_label_priority) } + end + + def merged_option + { 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 + + def title_option + { value: sort_value_title, text: sort_title_title, href: page_filter_path(sort: sort_value_title) } + end + def sort_direction_icon(sort_value) case sort_value when sort_value_milestone, sort_value_due_date, sort_value_merged_date, sort_value_closed_date, /_asc\z/ diff --git a/app/helpers/storage_helper.rb b/app/helpers/storage_helper.rb index a075ccc38f5..cb1a5f5ce0c 100644 --- a/app/helpers/storage_helper.rb +++ b/app/helpers/storage_helper.rb @@ -32,8 +32,9 @@ module StorageHelper { 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}%{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 }, + "You are currently using %{used_storage} of namespace storage. " \ + "View and manage your usage from %{strong_start}%{namespace_type} settings > Usage quotas%{strong_end}.")).html_safe % + { storage_enforcement_date: namespace.storage_enforcement_date, used_storage: storage_counter(namespace.root_storage_statistics&.storage_size || 0), strong_start: "<strong>".html_safe, strong_end: "</strong>".html_safe, namespace_type: namespace.type }, variant: 'warning', callouts_path: namespace.user_namespace? ? callouts_path : group_callouts_path, callouts_feature_name: storage_enforcement_banner_user_callouts_feature_name(namespace), diff --git a/app/helpers/system_note_helper.rb b/app/helpers/system_note_helper.rb index b45ce10a2f6..82847534d8e 100644 --- a/app/helpers/system_note_helper.rb +++ b/app/helpers/system_note_helper.rb @@ -43,7 +43,8 @@ module SystemNoteHelper 'issue_type' => 'pencil-square', 'attention_requested' => 'user', 'attention_request_removed' => 'user', - 'contact' => 'users' + 'contact' => 'users', + 'timeline_event' => 'clock' }.freeze def system_note_icon_name(note) diff --git a/app/helpers/todos_helper.rb b/app/helpers/todos_helper.rb index 60bf79f3114..d3cc922423d 100644 --- a/app/helpers/todos_helper.rb +++ b/app/helpers/todos_helper.rb @@ -17,12 +17,11 @@ module TodosHelper case todo.action 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::MENTIONED, Todo::DIRECTLY_ADDRESSED then "mentioned #{todo_action_subject(todo)} on" 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' - when Todo::DIRECTLY_ADDRESSED then "directly addressed #{todo_action_subject(todo)} on" when Todo::MERGE_TRAIN_REMOVED then "Removed from Merge Train:" when Todo::ATTENTION_REQUESTED then 'requested your attention on' end @@ -151,8 +150,7 @@ module TodosHelper { id: Todo::REVIEW_REQUESTED, text: 'Review requested' }, { id: Todo::MENTIONED, text: 'Mentioned' }, { id: Todo::MARKED, text: 'Added' }, - { id: Todo::BUILD_FAILED, text: 'Pipelines' }, - { id: Todo::DIRECTLY_ADDRESSED, text: 'Directly addressed' } + { id: Todo::BUILD_FAILED, text: 'Pipelines' } ] end diff --git a/app/helpers/tracking_helper.rb b/app/helpers/tracking_helper.rb index 1beb88548c5..9ef57a57d62 100644 --- a/app/helpers/tracking_helper.rb +++ b/app/helpers/tracking_helper.rb @@ -2,7 +2,7 @@ module TrackingHelper def tracking_attrs(label, action, property) - return {} unless tracking_enabled? + return {} unless ::Gitlab::Tracking.enabled? { data: { @@ -16,11 +16,4 @@ module TrackingHelper def tracking_attrs_data(label, action, property) tracking_attrs(label, action, property).fetch(:data, {}) end - - private - - def tracking_enabled? - Rails.env.production? && - ::Gitlab::Tracking.enabled? - end end diff --git a/app/helpers/users/group_callouts_helper.rb b/app/helpers/users/group_callouts_helper.rb index 9a9fce4d7e3..0aa4eb89499 100644 --- a/app/helpers/users/group_callouts_helper.rb +++ b/app/helpers/users/group_callouts_helper.rb @@ -31,5 +31,3 @@ module Users end end end - -Users::GroupCalloutsHelper.prepend_mod diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb index 1247f9ae260..fd460d71867 100644 --- a/app/helpers/users_helper.rb +++ b/app/helpers/users_helper.rb @@ -125,7 +125,7 @@ module UsersHelper end def ban_feature_available? - Feature.enabled?(:ban_user_feature_flag, default_enabled: :yaml) + Feature.enabled?(:ban_user_feature_flag) end def confirm_user_data(user) diff --git a/app/helpers/workhorse_helper.rb b/app/helpers/workhorse_helper.rb index 70df696510a..f1ddc2e902e 100644 --- a/app/helpers/workhorse_helper.rb +++ b/app/helpers/workhorse_helper.rb @@ -38,6 +38,8 @@ module WorkhorseHelper # Send an entry from artifacts through Workhorse and set safe content type def send_artifacts_entry(file, entry) headers.store(*Gitlab::Workhorse.send_artifacts_entry(file, entry)) + headers.store(*Gitlab::Workhorse.detect_content_type) + head :ok end |