summaryrefslogtreecommitdiff
path: root/app/helpers
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-06-20 11:10:13 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2022-06-20 11:10:13 +0000
commit0ea3fcec397b69815975647f5e2aa5fe944a8486 (patch)
tree7979381b89d26011bcf9bdc989a40fcc2f1ed4ff /app/helpers
parent72123183a20411a36d607d70b12d57c484394c8e (diff)
downloadgitlab-ce-0ea3fcec397b69815975647f5e2aa5fe944a8486.tar.gz
Add latest changes from gitlab-org/gitlab@15-1-stable-eev15.1.0-rc42
Diffstat (limited to 'app/helpers')
-rw-r--r--app/helpers/access_tokens_helper.rb4
-rw-r--r--app/helpers/admin/application_settings/settings_helper.rb16
-rw-r--r--app/helpers/application_helper.rb1
-rw-r--r--app/helpers/application_settings_helper.rb28
-rw-r--r--app/helpers/breadcrumbs_helper.rb2
-rw-r--r--app/helpers/ci/pipeline_editor_helper.rb1
-rw-r--r--app/helpers/ci/runners_helper.rb8
-rw-r--r--app/helpers/custom_metrics_helper.rb2
-rw-r--r--app/helpers/diff_helper.rb27
-rw-r--r--app/helpers/emails_helper.rb2
-rw-r--r--app/helpers/environments_helper.rb3
-rw-r--r--app/helpers/form_helper.rb58
-rw-r--r--app/helpers/groups/crm_settings_helper.rb9
-rw-r--r--app/helpers/groups/group_members_helper.rb15
-rw-r--r--app/helpers/groups_helper.rb34
-rw-r--r--app/helpers/integrations_helper.rb10
-rw-r--r--app/helpers/invite_members_helper.rb2
-rw-r--r--app/helpers/issues_helper.rb20
-rw-r--r--app/helpers/jira_connect_helper.rb4
-rw-r--r--app/helpers/markup_helper.rb33
-rw-r--r--app/helpers/members_helper.rb2
-rw-r--r--app/helpers/merge_requests_helper.rb6
-rw-r--r--app/helpers/nav/new_dropdown_helper.rb2
-rw-r--r--app/helpers/nav/top_nav_helper.rb76
-rw-r--r--app/helpers/nav_helper.rb2
-rw-r--r--app/helpers/notes_helper.rb6
-rw-r--r--app/helpers/projects/pipeline_helper.rb8
-rw-r--r--app/helpers/projects/project_members_helper.rb29
-rw-r--r--app/helpers/projects_helper.rb61
-rw-r--r--app/helpers/search_helper.rb2
-rw-r--r--app/helpers/snippets_helper.rb12
-rw-r--r--app/helpers/sorting_helper.rb4
-rw-r--r--app/helpers/storage_helper.rb30
-rw-r--r--app/helpers/system_note_helper.rb8
-rw-r--r--app/helpers/tags_helper.rb9
-rw-r--r--app/helpers/todos_helper.rb23
-rw-r--r--app/helpers/tooling/visual_review_helper.rb26
-rw-r--r--app/helpers/users_helper.rb2
-rw-r--r--app/helpers/work_items_helper.rb10
39 files changed, 450 insertions, 147 deletions
diff --git a/app/helpers/access_tokens_helper.rb b/app/helpers/access_tokens_helper.rb
index d8d44601327..44200e84afb 100644
--- a/app/helpers/access_tokens_helper.rb
+++ b/app/helpers/access_tokens_helper.rb
@@ -29,7 +29,9 @@ module AccessTokensHelper
end
def expires_at_field_data
- {}
+ {
+ min_date: 1.day.from_now.iso8601
+ }
end
end
diff --git a/app/helpers/admin/application_settings/settings_helper.rb b/app/helpers/admin/application_settings/settings_helper.rb
new file mode 100644
index 00000000000..bd83ed19705
--- /dev/null
+++ b/app/helpers/admin/application_settings/settings_helper.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module Admin
+ module ApplicationSettings
+ module SettingsHelper
+ def inactive_projects_deletion_data(settings)
+ {
+ delete_inactive_projects: settings.delete_inactive_projects.to_s,
+ inactive_projects_delete_after_months: settings.inactive_projects_delete_after_months,
+ inactive_projects_min_size_mb: settings.inactive_projects_min_size_mb,
+ inactive_projects_send_warning_email_after_months: settings.inactive_projects_send_warning_email_after_months
+ }
+ end
+ end
+ end
+end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 8cdfc267693..d2cc50be509 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -1,6 +1,5 @@
# frozen_string_literal: true
-require 'digest/md5'
require 'uri'
module ApplicationHelper
diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb
index 9023cca18dc..cd31d2c75ab 100644
--- a/app/helpers/application_settings_helper.rb
+++ b/app/helpers/application_settings_helper.rb
@@ -270,6 +270,7 @@ module ApplicationSettingsHelper
:inactive_projects_min_size_mb,
:inactive_projects_send_warning_email_after_months,
:invisible_captcha_enabled,
+ :jira_connect_application_key,
:max_artifacts_size,
:max_attachment_size,
:max_export_size,
@@ -407,6 +408,7 @@ module ApplicationSettingsHelper
:container_registry_import_max_retries,
:container_registry_import_start_max_retries,
:container_registry_import_max_step_duration,
+ :container_registry_pre_import_tags_rate,
:container_registry_pre_import_timeout,
:container_registry_import_timeout,
:container_registry_import_target_plan,
@@ -511,6 +513,32 @@ module ApplicationSettingsHelper
def registration_features_can_be_prompted?
!Gitlab::CurrentSettings.usage_ping_enabled?
end
+
+ def signup_form_data
+ {
+ host: new_user_session_url(host: Gitlab.config.gitlab.host),
+ settings_path: general_admin_application_settings_path(anchor: 'js-signup-settings'),
+ signup_enabled: @application_setting[:signup_enabled].to_s,
+ require_admin_approval_after_user_signup: @application_setting[:require_admin_approval_after_user_signup].to_s,
+ send_user_confirmation_email: @application_setting[:send_user_confirmation_email].to_s,
+ minimum_password_length: @application_setting[:minimum_password_length],
+ minimum_password_length_min: ApplicationSetting::DEFAULT_MINIMUM_PASSWORD_LENGTH,
+ minimum_password_length_max: Devise.password_length.max,
+ minimum_password_length_help_link:
+ 'https://about.gitlab.com/handbook/security/#gitlab-password-policy-guidelines',
+ domain_allowlist_raw: @application_setting.domain_allowlist_raw,
+ new_user_signups_cap: @application_setting[:new_user_signups_cap].to_s,
+ domain_denylist_enabled: @application_setting[:domain_denylist_enabled].to_s,
+ denylist_type_raw_selected:
+ (@application_setting.domain_denylist.present? || @application_setting.domain_denylist.blank?).to_s,
+ domain_denylist_raw: @application_setting.domain_denylist_raw,
+ email_restrictions_enabled: @application_setting[:email_restrictions_enabled].to_s,
+ supported_syntax_link_url: 'https://github.com/google/re2/wiki/Syntax',
+ email_restrictions: @application_setting.email_restrictions.to_s,
+ after_sign_up_text: @application_setting[:after_sign_up_text].to_s,
+ pending_user_count: pending_user_count
+ }
+ end
end
ApplicationSettingsHelper.prepend_mod_with('ApplicationSettingsHelper')
diff --git a/app/helpers/breadcrumbs_helper.rb b/app/helpers/breadcrumbs_helper.rb
index 3a622a65685..38ed6e95a44 100644
--- a/app/helpers/breadcrumbs_helper.rb
+++ b/app/helpers/breadcrumbs_helper.rb
@@ -23,7 +23,7 @@ module BreadcrumbsHelper
def breadcrumb_list_item(link)
content_tag "li" do
- link + sprite_icon("angle-right", size: 8, css_class: "breadcrumbs-list-angle")
+ link + sprite_icon("chevron-lg-right", size: 8, css_class: "breadcrumbs-list-angle")
end
end
diff --git a/app/helpers/ci/pipeline_editor_helper.rb b/app/helpers/ci/pipeline_editor_helper.rb
index da773e3e8a8..bb3f7b5aa79 100644
--- a/app/helpers/ci/pipeline_editor_helper.rb
+++ b/app/helpers/ci/pipeline_editor_helper.rb
@@ -33,6 +33,7 @@ module Ci
"project-namespace" => project.namespace.full_path,
"runner-help-page-path" => help_page_path('ci/runners/index'),
"total-branches" => total_branches,
+ "validate-tab-illustration-path" => image_path('illustrations/project-run-CICD-pipelines-sm.svg'),
"yml-help-page-path" => help_page_path('ci/yaml/index')
}
end
diff --git a/app/helpers/ci/runners_helper.rb b/app/helpers/ci/runners_helper.rb
index 6366ca0dfb1..74318797069 100644
--- a/app/helpers/ci/runners_helper.rb
+++ b/app/helpers/ci/runners_helper.rb
@@ -65,7 +65,9 @@ module Ci
runner_install_help_page: 'https://docs.gitlab.com/runner/install/',
registration_token: Gitlab::CurrentSettings.runners_registration_token,
online_contact_timeout_secs: ::Ci::Runner::ONLINE_CONTACT_TIMEOUT.to_i,
- stale_timeout_secs: ::Ci::Runner::STALE_TIMEOUT.to_i
+ stale_timeout_secs: ::Ci::Runner::STALE_TIMEOUT.to_i,
+ empty_state_svg_path: image_path('illustrations/pipelines_empty.svg'),
+ empty_state_filtered_svg_path: image_path('illustrations/magnifying-glass.svg')
}
end
@@ -87,7 +89,9 @@ module Ci
group_full_path: group.full_path,
runner_install_help_page: 'https://docs.gitlab.com/runner/install/',
online_contact_timeout_secs: ::Ci::Runner::ONLINE_CONTACT_TIMEOUT.to_i,
- stale_timeout_secs: ::Ci::Runner::STALE_TIMEOUT.to_i
+ stale_timeout_secs: ::Ci::Runner::STALE_TIMEOUT.to_i,
+ empty_state_svg_path: image_path('illustrations/pipelines_empty.svg'),
+ empty_state_filtered_svg_path: image_path('illustrations/magnifying-glass.svg')
}
end
diff --git a/app/helpers/custom_metrics_helper.rb b/app/helpers/custom_metrics_helper.rb
index 5442120008a..8a9d94bd2a1 100644
--- a/app/helpers/custom_metrics_helper.rb
+++ b/app/helpers/custom_metrics_helper.rb
@@ -5,7 +5,7 @@ module CustomMetricsHelper
{
'custom-metrics-path' => url_for([project, metric]),
'metric-persisted' => metric.persisted?.to_s,
- 'edit-project-service-path' => edit_project_integration_path(project, ::Integrations::Prometheus),
+ 'edit-integration-path' => edit_project_settings_integration_path(project, ::Integrations::Prometheus),
'validate-query-path' => validate_query_project_prometheus_metrics_path(project),
'title' => metric.title.to_s,
'query' => metric.query.to_s,
diff --git a/app/helpers/diff_helper.rb b/app/helpers/diff_helper.rb
index 522593dd487..71c8296ad2e 100644
--- a/app/helpers/diff_helper.rb
+++ b/app/helpers/diff_helper.rb
@@ -225,6 +225,23 @@ module DiffHelper
end
end
+ def conflicts(allow_tree_conflicts: false)
+ return unless options[:merge_ref_head_diff]
+
+ conflicts_service = MergeRequests::Conflicts::ListService.new(merge_request, allow_tree_conflicts: allow_tree_conflicts) # rubocop:disable CodeReuse/ServiceClass
+
+ return unless allow_tree_conflicts || conflicts_service.can_be_resolved_in_ui?
+
+ conflicts_service.conflicts.files.index_by(&:path)
+ rescue Gitlab::Git::Conflict::Resolver::ConflictSideMissing
+ # This exception is raised when changes on a fork isn't present on canonical repo yet.
+ # We can't list conflicts until the canonical repo gets the references from the fork
+ # which happens asynchronously when updating MR.
+ #
+ # Return empty hash to indicate that there are no conflicts.
+ {}
+ end
+
private
def diff_btn(title, name, selected)
@@ -271,16 +288,6 @@ module DiffHelper
Gitlab::CodeNavigationPath.new(merge_request.project, merge_request.diff_head_sha)
end
- def conflicts(allow_tree_conflicts: false)
- return unless options[:merge_ref_head_diff]
-
- conflicts_service = MergeRequests::Conflicts::ListService.new(merge_request, allow_tree_conflicts: allow_tree_conflicts) # rubocop:disable CodeReuse/ServiceClass
-
- return unless allow_tree_conflicts || conflicts_service.can_be_resolved_in_ui?
-
- conflicts_service.conflicts.files.index_by(&:path)
- end
-
def log_overflow_limits(diff_files:, collection_overflow:)
if diff_files.any?(&:too_large?)
Gitlab::Metrics.add_event(:diffs_overflow_single_file_limits)
diff --git a/app/helpers/emails_helper.rb b/app/helpers/emails_helper.rb
index 59731dc2f6f..c23d905a008 100644
--- a/app/helpers/emails_helper.rb
+++ b/app/helpers/emails_helper.rb
@@ -62,7 +62,7 @@ module EmailsHelper
end
def header_logo
- if current_appearance&.header_logo?
+ if current_appearance&.header_logo? && !current_appearance.header_logo.filename.ends_with?('.svg')
image_tag(
current_appearance.header_logo_path,
style: 'height: 50px'
diff --git a/app/helpers/environments_helper.rb b/app/helpers/environments_helper.rb
index 3b60bda8605..59d43c51db2 100644
--- a/app/helpers/environments_helper.rb
+++ b/app/helpers/environments_helper.rb
@@ -59,7 +59,7 @@ module EnvironmentsHelper
return {} unless project
{
- 'settings_path' => edit_project_integration_path(project, 'prometheus'),
+ 'settings_path' => edit_project_settings_integration_path(project, 'prometheus'),
'clusters_path' => project_clusters_path(project),
'dashboards_endpoint' => project_performance_monitoring_dashboards_path(project, format: :json),
'default_branch' => project.default_branch,
@@ -102,7 +102,6 @@ module EnvironmentsHelper
'metrics_endpoint' => additional_metrics_project_environment_path(project, environment, format: :json),
'dashboard_endpoint' => metrics_dashboard_project_environment_path(project, environment, format: :json),
'deployments_endpoint' => project_environment_deployments_path(project, environment, format: :json),
- 'alerts_endpoint' => project_prometheus_alerts_path(project, environment_id: environment.id, format: :json),
'operations_settings_path' => project_settings_operations_path(project),
'can_access_operations_settings' => can?(current_user, :admin_operations, project).to_s,
'panel_preview_endpoint' => project_metrics_dashboards_builder_path(project, format: :json)
diff --git a/app/helpers/form_helper.rb b/app/helpers/form_helper.rb
index 3a5dcb4e664..17812aed3ff 100644
--- a/app/helpers/form_helper.rb
+++ b/app/helpers/form_helper.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module FormHelper
- def form_errors(model, type: 'form', truncate: [])
+ def form_errors(model, type: 'form', truncate: [], pajamas_alert: false)
errors = model.errors
return unless errors.any?
@@ -14,21 +14,37 @@ module FormHelper
truncate = Array.wrap(truncate)
- tag.div(class: 'alert alert-danger', id: 'error_explanation') do
- tag.h4(headline) <<
- tag.ul do
- messages = errors.map do |error|
- attribute = error.attribute
- message = error.message
-
- message = html_escape_once(errors.full_message(attribute, message)).html_safe
- message = tag.span(message, class: 'str-truncated-100') if truncate.include?(attribute)
-
- tag.li(message)
+ messages = errors.map do |error|
+ attribute = error.attribute
+ message = error.message
+
+ message = html_escape_once(errors.full_message(attribute, message)).html_safe
+ message = tag.span(message, class: 'str-truncated-100') if truncate.include?(attribute)
+ message = append_help_page_link(message, error.options) if error.options[:help_page_url].present?
+
+ tag.li(message)
+ end.join.html_safe
+
+ if pajamas_alert
+ render Pajamas::AlertComponent.new(
+ variant: :danger,
+ title: headline,
+ dismissible: false,
+ alert_options: { id: 'error_explanation', class: 'gl-mb-5' }
+ ) do |c|
+ c.body do
+ tag.ul(class: 'gl-pl-5 gl-mb-0') do
+ messages
end
-
- messages.join.html_safe
end
+ end
+ else
+ tag.div(class: 'alert alert-danger', id: 'error_explanation') do
+ tag.h4(headline) <<
+ tag.ul do
+ messages
+ end
+ end
end
end
@@ -120,6 +136,20 @@ module FormHelper
private
+ def append_help_page_link(message, options)
+ help_page_url = options[:help_page_url]
+ help_link_text = options[:help_link_text] || _('Learn more.')
+
+ help_link = link_to(
+ help_link_text,
+ help_page_url,
+ target: '_blank',
+ rel: 'noopener noreferrer'
+ )
+
+ message + " #{help_link}".html_safe
+ end
+
def multiple_assignees_dropdown_options(options)
new_options = options.dup
diff --git a/app/helpers/groups/crm_settings_helper.rb b/app/helpers/groups/crm_settings_helper.rb
deleted file mode 100644
index d7ca25a9d1b..00000000000
--- a/app/helpers/groups/crm_settings_helper.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-module Groups
- module CrmSettingsHelper
- def crm_feature_available?(group)
- Feature.enabled?(:customer_relations, group)
- end
- end
-end
diff --git a/app/helpers/groups/group_members_helper.rb b/app/helpers/groups/group_members_helper.rb
index ca61c4da41c..37b23345d2a 100644
--- a/app/helpers/groups/group_members_helper.rb
+++ b/app/helpers/groups/group_members_helper.rb
@@ -20,6 +20,13 @@ module Groups::GroupMembersHelper
}
end
+ def group_member_header_subtext(group)
+ html_escape(_('You can invite a new member to ' \
+ '%{strong_start}%{group_name}%{strong_end}.')) % { group_name: group.name,
+ strong_start: '<strong>'.html_safe,
+ strong_end: '</strong>'.html_safe }
+ end
+
private
def group_members_serialized(group, members)
@@ -53,12 +60,8 @@ module Groups::GroupMembersHelper
end
def group_group_links_list_data(group, include_relations, search)
- 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
- group_links = group.shared_with_group_links
- end
+ group_links = group_group_links(group, include_relations)
+ group_links = group_links.search(search) if search
{
members: group_group_links_serialized(group, group_links),
diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb
index c58a365b884..9ea9509bc28 100644
--- a/app/helpers/groups_helper.rb
+++ b/app/helpers/groups_helper.rb
@@ -144,6 +144,40 @@ module GroupsHelper
false
end
+ def group_name_and_path_app_data(group)
+ parent = group.parent
+
+ {
+ base_path: URI.join(root_url, parent&.full_path || "").to_s,
+ mattermost_enabled: Gitlab.config.mattermost.enabled.to_s
+ }
+ end
+
+ def subgroups_and_projects_list_app_data(group)
+ {
+ show_schema_markup: 'true',
+ new_subgroup_path: new_group_path(parent_id: group.id),
+ new_project_path: new_project_path(namespace_id: group.id),
+ new_subgroup_illustration: image_path('illustrations/subgroup-create-new-sm.svg'),
+ new_project_illustration: image_path('illustrations/project-create-new-sm.svg'),
+ empty_subgroup_illustration: image_path('illustrations/empty-state/empty-subgroup-md.svg'),
+ render_empty_state: 'true',
+ can_create_subgroups: can?(current_user, :create_subgroup, group).to_s,
+ can_create_projects: can?(current_user, :create_projects, group).to_s
+ }
+ end
+
+ def enabled_git_access_protocol_options_for_group
+ case ::Gitlab::CurrentSettings.enabled_git_access_protocol
+ when nil, ""
+ [[_("Both SSH and HTTP(S)"), "all"], [_("Only SSH"), "ssh"], [_("Only HTTP(S)"), "http"]]
+ when "ssh"
+ [[_("Only SSH"), "ssh"]]
+ when "http"
+ [[_("Only HTTP(S)"), "http"]]
+ end
+ end
+
private
def group_title_link(group, hidable: false, show_avatar: false, for_dropdown: false)
diff --git a/app/helpers/integrations_helper.rb b/app/helpers/integrations_helper.rb
index 862938ac961..82d4ceee44e 100644
--- a/app/helpers/integrations_helper.rb
+++ b/app/helpers/integrations_helper.rb
@@ -58,7 +58,7 @@ module IntegrationsHelper
def scoped_integration_path(integration, project: nil, group: nil)
if project.present?
- project_integration_path(project, integration)
+ project_settings_integration_path(project, integration)
elsif group.present?
group_settings_integration_path(group, integration)
else
@@ -68,7 +68,7 @@ module IntegrationsHelper
def scoped_edit_integration_path(integration, project: nil, group: nil)
if project.present?
- edit_project_integration_path(project, integration)
+ edit_project_settings_integration_path(project, integration)
elsif group.present?
edit_group_settings_integration_path(group, integration)
else
@@ -82,7 +82,7 @@ module IntegrationsHelper
def scoped_test_integration_path(integration, project: nil, group: nil)
if project.present?
- test_project_integration_path(project, integration)
+ test_project_settings_integration_path(project, integration)
elsif group.present?
test_group_settings_integration_path(group, integration)
else
@@ -233,11 +233,11 @@ module IntegrationsHelper
end
def trigger_events_for_integration(integration)
- ServiceEventSerializer.new(service: integration).represent(integration.configurable_events).to_json
+ Integrations::EventSerializer.new(integration: integration).represent(integration.configurable_events).to_json
end
def fields_for_integration(integration)
- ServiceFieldSerializer.new(service: integration).represent(integration.global_fields).to_json
+ Integrations::FieldSerializer.new(integration: integration).represent(integration.global_fields).to_json
end
def integration_level(integration)
diff --git a/app/helpers/invite_members_helper.rb b/app/helpers/invite_members_helper.rb
index e46270ab819..5d537767eaf 100644
--- a/app/helpers/invite_members_helper.rb
+++ b/app/helpers/invite_members_helper.rb
@@ -29,7 +29,7 @@ module InviteMembersHelper
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
+ access_levels: member_class.permissible_access_level_roles(current_user, source).to_json
}.merge(group_select_data(source))
end
diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb
index 60dba73447c..a157b1b7b21 100644
--- a/app/helpers/issues_helper.rb
+++ b/app/helpers/issues_helper.rb
@@ -28,18 +28,16 @@ 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'
+ 'gl-bg-orange-500'
elsif item.try(:merged?)
- updated_mr_header_enabled ? 'badge-info' : 'status-box-mr-merged'
+ 'badge-info'
elsif item.closed?
- item.is_a?(MergeRequest) && updated_mr_header_enabled ? 'badge-danger' : 'status-box-mr-closed'
+ item.is_a?(MergeRequest) ? 'badge-danger' : 'gl-bg-red-500'
elsif item.try(:upcoming?)
- 'status-box-upcoming'
+ 'gl-bg-gray-500'
else
- item.is_a?(MergeRequest) && updated_mr_header_enabled ? 'badge-success' : 'status-box-open'
+ item.is_a?(MergeRequest) ? 'badge-success' : 'gl-bg-green-500'
end
end
@@ -218,6 +216,8 @@ module IssuesHelper
can_bulk_update: can?(current_user, :admin_issue, project).to_s,
can_edit: can?(current_user, :admin_project, project).to_s,
can_import_issues: can?(current_user, :import_issues, @project).to_s,
+ can_read_crm_contact: can?(current_user, :read_crm_contact, project.group).to_s,
+ can_read_crm_organization: can?(current_user, :read_crm_organization, project.group).to_s,
email: current_user&.notification_email_or_default,
emails_help_page_path: help_page_path('development/emails', anchor: 'email-namespace'),
export_csv_path: export_csv_project_issues_path(project),
@@ -238,8 +238,12 @@ module IssuesHelper
def group_issues_list_data(group, current_user)
common_issues_list_data(group, current_user).merge(
+ can_create_projects: can?(current_user, :create_projects, group).to_s,
+ can_read_crm_contact: can?(current_user, :read_crm_contact, group).to_s,
+ can_read_crm_organization: can?(current_user, :read_crm_organization, group).to_s,
has_any_issues: @has_issues.to_s,
- has_any_projects: @has_projects.to_s
+ has_any_projects: @has_projects.to_s,
+ new_project_path: new_project_path(namespace_id: group.id)
)
end
diff --git a/app/helpers/jira_connect_helper.rb b/app/helpers/jira_connect_helper.rb
index 30f29e002b8..4ddfb0224d1 100644
--- a/app/helpers/jira_connect_helper.rb
+++ b/app/helpers/jira_connect_helper.rb
@@ -19,7 +19,7 @@ module JiraConnectHelper
def jira_connect_oauth_data
oauth_authorize_url = oauth_authorization_url(
- client_id: ENV['JIRA_CONNECT_OAUTH_CLIENT_ID'],
+ client_id: Gitlab::CurrentSettings.jira_connect_application_key,
response_type: 'code',
scope: 'api',
redirect_uri: jira_connect_oauth_callbacks_url,
@@ -32,7 +32,7 @@ module JiraConnectHelper
state: oauth_state,
oauth_token_payload: {
grant_type: :authorization_code,
- client_id: ENV['JIRA_CONNECT_OAUTH_CLIENT_ID'],
+ client_id: Gitlab::CurrentSettings.jira_connect_application_key,
redirect_uri: jira_connect_oauth_callbacks_url
}
}
diff --git a/app/helpers/markup_helper.rb b/app/helpers/markup_helper.rb
index 7a4cc61af79..777d485797f 100644
--- a/app/helpers/markup_helper.rb
+++ b/app/helpers/markup_helper.rb
@@ -6,6 +6,12 @@ module MarkupHelper
include ActionView::Helpers::TextHelper
include ActionView::Context
+ # Let's increase the render timeout
+ # For a smaller one, a test that renders the blob content statically fails
+ # We can consider removing this custom timeout when refactor_blob_viewer FF is removed:
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/324351
+ RENDER_TIMEOUT = 5.seconds
+
def plain?(filename)
Gitlab::MarkupHelper.plain?(filename)
end
@@ -88,7 +94,10 @@ module MarkupHelper
text,
tags: tags,
attributes: Rails::Html::WhiteListSanitizer.allowed_attributes +
- %w(style data-src data-name data-unicode-version data-iid data-project-path data-mr-title data-html)
+ %w(
+ style data-src data-name data-unicode-version data-html
+ data-reference-type data-project-path data-iid data-mr-title
+ )
)
# since <img> tags are stripped, this can leave empty <a> tags hanging around
@@ -136,14 +145,22 @@ module MarkupHelper
def markup_unsafe(file_name, text, context = {})
return '' unless text.present?
- if gitlab_markdown?(file_name)
- markdown_unsafe(text, context)
- elsif asciidoc?(file_name)
- asciidoc_unsafe(text, context)
- elsif plain?(file_name)
- plain_unsafe(text)
+ markup = proc do
+ if gitlab_markdown?(file_name)
+ markdown_unsafe(text, context)
+ elsif asciidoc?(file_name)
+ asciidoc_unsafe(text, context)
+ elsif plain?(file_name)
+ plain_unsafe(text)
+ else
+ other_markup_unsafe(file_name, text, context)
+ end
+ end
+
+ if Feature.enabled?(:markup_rendering_timeout, @project)
+ Gitlab::RenderTimeout.timeout(foreground: RENDER_TIMEOUT, &markup)
else
- other_markup_unsafe(file_name, text, context)
+ markup.call
end
rescue StandardError => e
Gitlab::ErrorTracking.track_exception(e, project_id: @project&.id, file_name: file_name)
diff --git a/app/helpers/members_helper.rb b/app/helpers/members_helper.rb
index aac49cfa234..4b1cbd3f1ae 100644
--- a/app/helpers/members_helper.rb
+++ b/app/helpers/members_helper.rb
@@ -84,3 +84,5 @@ module MembersHelper
}
end
end
+
+MembersHelper.prepend_mod_with('MembersHelper')
diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb
index e1c9e7d3896..d840223a066 100644
--- a/app/helpers/merge_requests_helper.rb
+++ b/app/helpers/merge_requests_helper.rb
@@ -139,7 +139,7 @@ module MergeRequestsHelper
end
def toggle_draft_merge_request_path(issuable)
- wip_event = issuable.work_in_progress? ? 'unwip' : 'wip'
+ wip_event = issuable.draft? ? 'ready' : 'draft'
issuable_path(issuable, { merge_request: { wip_event: wip_event } })
end
@@ -246,13 +246,13 @@ module MergeRequestsHelper
''
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'
+ link_to branch, branch_path, title: branch, class: 'gl-text-blue-500! 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'
+ 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-text-blue-500! 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
diff --git a/app/helpers/nav/new_dropdown_helper.rb b/app/helpers/nav/new_dropdown_helper.rb
index 715a5a02b50..469d6c1a7eb 100644
--- a/app/helpers/nav/new_dropdown_helper.rb
+++ b/app/helpers/nav/new_dropdown_helper.rb
@@ -16,7 +16,7 @@ module Nav
menu_sections.push(general_menu_section)
{
- title: _("New..."),
+ title: _("Create new"),
menu_sections: menu_sections.select { |x| x.fetch(:menu_items).any? }
}
end
diff --git a/app/helpers/nav/top_nav_helper.rb b/app/helpers/nav/top_nav_helper.rb
index 9420c95c9ce..3ceb60251c2 100644
--- a/app/helpers/nav/top_nav_helper.rb
+++ b/app/helpers/nav/top_nav_helper.rb
@@ -127,7 +127,7 @@ module Nav
href: dashboard_milestones_path,
active: active_nav_link?(controller: 'dashboard/milestones'),
icon: 'clock',
- data: { qa_selector: 'milestones_link' },
+ data: { qa_selector: 'milestones_link', **menu_data_tracking_attrs('milestones') },
shortcut_class: 'dashboard-shortcuts-milestones'
)
end
@@ -135,7 +135,7 @@ module Nav
if dashboard_nav_link?(:snippets)
builder.add_primary_menu_item_with_shortcut(
active: active_nav_link?(controller: 'dashboard/snippets'),
- data: { qa_selector: 'snippets_link' },
+ data: { qa_selector: 'snippets_link', **menu_data_tracking_attrs('snippets') },
href: dashboard_snippets_path,
**snippets_menu_item_attrs
)
@@ -148,7 +148,7 @@ module Nav
href: activity_dashboard_path,
active: active_nav_link?(path: 'dashboard#activity'),
icon: 'history',
- data: { qa_selector: 'activity_link' },
+ data: { qa_selector: 'activity_link', **menu_data_tracking_attrs('activity') },
shortcut_class: 'dashboard-shortcuts-activity'
)
end
@@ -158,13 +158,16 @@ module Nav
# we should be good.
# rubocop: disable Cop/UserAdmin
if current_user&.admin?
+ title = _('Admin')
+
builder.add_secondary_menu_item(
id: 'admin',
- title: _('Admin'),
+ title: title,
active: active_nav_link?(controller: 'admin/dashboard'),
icon: 'admin',
css_class: 'qa-admin-area-link',
- href: admin_root_path
+ href: admin_root_path,
+ data: { qa_selector: 'menu_item_link', qa_title: title, **menu_data_tracking_attrs(title) }
)
end
@@ -176,15 +179,18 @@ module Nav
active: active_nav_link?(controller: 'admin/sessions'),
icon: 'lock-open',
href: destroy_admin_session_path,
- data: { method: 'post' }
+ data: { method: 'post', **menu_data_tracking_attrs('leave_admin_mode') }
)
elsif current_user.admin?
+ title = _('Enter Admin Mode')
+
builder.add_secondary_menu_item(
id: 'enter_admin_mode',
- title: _('Enter Admin Mode'),
+ title: title,
active: active_nav_link?(controller: 'admin/sessions'),
icon: 'lock',
- href: new_admin_session_path
+ href: new_admin_session_path,
+ data: { qa_selector: 'menu_item_link', qa_title: title, **menu_data_tracking_attrs(title) }
)
end
end
@@ -218,6 +224,14 @@ module Nav
}
end
+ def menu_data_tracking_attrs(label)
+ tracking_attrs(
+ "menu_#{label.underscore.parameterize(separator: '_')}",
+ 'click_dropdown',
+ 'navigation'
+ )[:data] || {}
+ end
+
def container_view_props(namespace:, current_item:, submenu:)
{
namespace: namespace,
@@ -260,21 +274,51 @@ module Nav
def projects_submenu_items(builder:)
# These project links come from `app/views/layouts/nav/projects_dropdown/_show.html.haml`
- builder.add_primary_menu_item(id: 'your', title: _('Your projects'), href: dashboard_projects_path)
- builder.add_primary_menu_item(id: 'starred', title: _('Starred projects'), href: starred_dashboard_projects_path)
- builder.add_primary_menu_item(id: 'explore', title: _('Explore projects'), href: explore_root_path)
- builder.add_primary_menu_item(id: 'topics', title: _('Explore topics'), href: topics_explore_projects_path)
- builder.add_secondary_menu_item(id: 'create', title: _('Create new project'), href: new_project_path)
+ [
+ { id: 'your', title: _('Your projects'), href: dashboard_projects_path },
+ { id: 'starred', title: _('Starred projects'), href: starred_dashboard_projects_path },
+ { id: 'explore', title: _('Explore projects'), href: explore_root_path },
+ { id: 'topics', title: _('Explore topics'), href: topics_explore_projects_path }
+ ].each do |item|
+ builder.add_primary_menu_item(
+ **item,
+ data: { qa_selector: 'menu_item_link', qa_title: item[:title], **menu_data_tracking_attrs(item[:title]) }
+ )
+ end
+
+ title = _('Create new project')
+
+ builder.add_secondary_menu_item(
+ id: 'create',
+ title: title,
+ href: new_project_path,
+ data: { qa_selector: 'menu_item_link', qa_title: title, **menu_data_tracking_attrs(title) }
+ )
end
def groups_submenu
# These group links come from `app/views/layouts/nav/groups_dropdown/_show.html.haml`
builder = ::Gitlab::Nav::TopNavMenuBuilder.new
- builder.add_primary_menu_item(id: 'your', title: _('Your groups'), href: dashboard_groups_path)
- builder.add_primary_menu_item(id: 'explore', title: _('Explore groups'), href: explore_groups_path)
+
+ [
+ { id: 'your', title: _('Your groups'), href: dashboard_groups_path },
+ { id: 'explore', title: _('Explore groups'), href: explore_groups_path }
+ ].each do |item|
+ builder.add_primary_menu_item(
+ **item,
+ data: { qa_selector: 'menu_item_link', qa_title: item[:title], **menu_data_tracking_attrs(item[:title]) }
+ )
+ end
if current_user.can_create_group?
- builder.add_secondary_menu_item(id: 'create', title: _('Create group'), href: new_group_path)
+ title = _('Create group')
+
+ builder.add_secondary_menu_item(
+ id: 'create',
+ title: title,
+ href: new_group_path,
+ data: { qa_selector: 'menu_item_link', qa_title: title, **menu_data_tracking_attrs(title) }
+ )
end
builder.build
diff --git a/app/helpers/nav_helper.rb b/app/helpers/nav_helper.rb
index 37cd491e19f..4d6ab7b8bf9 100644
--- a/app/helpers/nav_helper.rb
+++ b/app/helpers/nav_helper.rb
@@ -21,7 +21,7 @@ module NavHelper
def page_gutter_class
moved_sidebar_enabled = current_controller?('merge_requests') && moved_mr_sidebar_enabled?
- if page_has_markdown?
+ if page_has_markdown? && !current_controller?('conflicts')
if cookies[:collapsed_gutter] == 'true'
["page-gutter", "#{'right-sidebar-collapsed' unless moved_sidebar_enabled}"]
else
diff --git a/app/helpers/notes_helper.rb b/app/helpers/notes_helper.rb
index 1afdb7a0ab9..b47f4633348 100644
--- a/app/helpers/notes_helper.rb
+++ b/app/helpers/notes_helper.rb
@@ -175,9 +175,7 @@ module NotesHelper
end
end
- def notes_data(issuable, start_at_zero = false)
- initial_last_fetched_at = start_at_zero ? 0 : Time.current.to_i * ::Gitlab::UpdatedNotesPaginator::MICROSECOND
-
+ def notes_data(issuable)
data = {
discussionsPath: discussions_path(issuable),
registerPath: new_session_path(:user, redirect_to_referer: 'yes', anchor: 'register-pane'),
@@ -188,7 +186,7 @@ module NotesHelper
reopenPath: reopen_issuable_path(issuable),
notesPath: notes_url,
prerenderedNotesCount: issuable.capped_notes_count(MAX_PRERENDERED_NOTES),
- lastFetchedAt: initial_last_fetched_at,
+ lastFetchedAt: Time.current.to_i * NotesActions::MICROSECOND,
notesFilter: current_user&.notes_filter_for(issuable)
}
diff --git a/app/helpers/projects/pipeline_helper.rb b/app/helpers/projects/pipeline_helper.rb
index 286026bc290..eeee8290914 100644
--- a/app/helpers/projects/pipeline_helper.rb
+++ b/app/helpers/projects/pipeline_helper.rb
@@ -2,13 +2,19 @@
module Projects
module PipelineHelper
+ extend ::Ci::BuildsHelper
+
def js_pipeline_tabs_data(project, pipeline)
{
can_generate_codequality_reports: pipeline.can_generate_codequality_reports?.to_json,
+ failed_jobs_count: pipeline.failed_builds.count,
+ failed_jobs_summary: prepare_failed_jobs_summary_data(pipeline.failed_builds),
+ full_path: project.full_path,
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
+ pipeline_project_path: project.full_path,
+ total_job_count: pipeline.total_size
}
end
end
diff --git a/app/helpers/projects/project_members_helper.rb b/app/helpers/projects/project_members_helper.rb
index 980c8ca6b80..d5cc2b72ae9 100644
--- a/app/helpers/projects/project_members_helper.rb
+++ b/app/helpers/projects/project_members_helper.rb
@@ -12,8 +12,35 @@ module Projects::ProjectMembersHelper
}.to_json
end
+ def project_member_header_subtext(project)
+ if can?(current_user, :admin_project_member, project)
+ share_project_description(project)
+ else
+ html_escape(_("Members can be added by project " \
+ "%{i_open}Maintainers%{i_close} or %{i_open}Owners%{i_close}")) % {
+ i_open: '<i>'.html_safe, i_close: '</i>'.html_safe
+ }
+ end
+ end
+
private
+ def share_project_description(project)
+ share_with_group = project.allowed_to_share_with_group?
+ share_with_members = !membership_locked?
+
+ description =
+ if share_with_group && share_with_members
+ _("You can invite a new member to %{project_name} or invite another group.")
+ elsif share_with_group
+ _("You can invite another group to %{project_name}.")
+ elsif share_with_members
+ _("You can invite a new member to %{project_name}.")
+ end
+
+ html_escape(description) % { project_name: tag.strong(project.name) }
+ end
+
def project_members_serialized(project, members)
MemberSerializer.new.represent(members, { current_user: current_user, group: project.group, source: project })
end
@@ -38,3 +65,5 @@ module Projects::ProjectMembersHelper
}
end
end
+
+Projects::ProjectMembersHelper.prepend_mod_with('Projects::ProjectMembersHelper')
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index c3f22dc7693..6112d05f37d 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -1,6 +1,8 @@
# frozen_string_literal: true
module ProjectsHelper
+ include Gitlab::Utils::StrongMemoize
+
def project_incident_management_setting
@project_incident_management_setting ||= @project.incident_management_setting ||
@project.build_incident_management_setting
@@ -331,22 +333,6 @@ module ProjectsHelper
false
end
- def share_project_description(project)
- share_with_group = project.allowed_to_share_with_group?
- share_with_members = !membership_locked?
-
- description =
- if share_with_group && share_with_members
- _("You can invite a new member to %{project_name} or invite another group.")
- elsif share_with_group
- _("You can invite another group to %{project_name}.")
- elsif share_with_members
- _("You can invite a new member to %{project_name}.")
- end
-
- html_escape(description) % { project_name: tag.strong(project.name) }
- end
-
def metrics_external_dashboard_url
@project.metrics_setting_external_dashboard_url
end
@@ -446,6 +432,30 @@ module ProjectsHelper
configure_oauth_import_message('GitLab.com', help_page_path("integration/gitlab"))
end
+ def show_inactive_project_deletion_banner?(project)
+ return false unless project.present? && project.saved?
+ return false unless delete_inactive_projects?
+ return false unless Feature.enabled?(:inactive_projects_deletion, project.root_namespace)
+
+ project.inactive?
+ end
+
+ def inactive_project_deletion_date(project)
+ Gitlab::InactiveProjectsDeletionWarningTracker.new(project.id).scheduled_deletion_date
+ end
+
+ def show_clusters_alert?(project)
+ Gitlab.com? && can_admin_associated_clusters?(project)
+ end
+
+ def clusters_deprecation_alert_message
+ if has_active_license?
+ s_('ClusterIntegration|The certificate-based Kubernetes integration has been deprecated and will be turned off at the end of November 2022. Please %{linkStart}migrate to the GitLab agent for Kubernetes%{linkEnd} or reach out to GitLab support.')
+ else
+ s_('ClusterIntegration|The certificate-based Kubernetes integration has been deprecated and will be turned off at the end of November 2022. Please %{linkStart}migrate to the GitLab agent for Kubernetes%{linkEnd}.')
+ end
+ end
+
private
def configure_oauth_import_message(provider, help_url)
@@ -596,6 +606,7 @@ module ProjectsHelper
feature = project.project_feature
{
packagesEnabled: !!project.packages_enabled,
+ packageRegistryAccessLevel: feature.package_registry_access_level,
visibilityLevel: project.visibility_level,
requestAccessEnabled: !!project.request_access_enabled,
issuesAccessLevel: feature.issues_access_level,
@@ -736,6 +747,24 @@ module ProjectsHelper
link_to(name, url)
end
end
+
+ def delete_inactive_projects?
+ strong_memoize(:delete_inactive_projects_setting) do
+ ::Gitlab::CurrentSettings.delete_inactive_projects?
+ end
+ end
+end
+
+def can_admin_associated_clusters?(project)
+ can_admin_project_clusters?(project) || can_admin_group_clusters?(project)
+end
+
+def can_admin_project_clusters?(project)
+ project.clusters.any? && can?(current_user, :admin_cluster, project)
+end
+
+def can_admin_group_clusters?(project)
+ project.group && project.group.clusters.any? && can?(current_user, :admin_cluster, project.group)
end
ProjectsHelper.prepend_mod_with('ProjectsHelper')
diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb
index 69bea0abd88..c8750cd9b52 100644
--- a/app/helpers/search_helper.rb
+++ b/app/helpers/search_helper.rb
@@ -117,6 +117,8 @@ module SearchHelper
end
def repository_ref(project)
+ return project.default_branch unless params[:project_id]
+
# Always #to_s the repository_ref param in case the value is also a number
params[:repository_ref].to_s.presence || project.default_branch
end
diff --git a/app/helpers/snippets_helper.rb b/app/helpers/snippets_helper.rb
index 78b204fefe9..8558c664977 100644
--- a/app/helpers/snippets_helper.rb
+++ b/app/helpers/snippets_helper.rb
@@ -62,6 +62,18 @@ module SnippetsHelper
rel: 'noopener noreferrer')
end
+ def embedded_copy_snippet_button(blob)
+ return unless blob.rendered_as_text?(ignore_errors: false)
+
+ content_tag(:button,
+ class: 'gl-button btn btn-default copy-to-clipboard-btn',
+ title: 'Copy snippet contents',
+ onclick: "copyToClipboard('.blob-content[data-blob-id=\"#{blob.id}\"] > pre')"
+ ) do
+ external_snippet_icon('copy-to-clipboard')
+ end
+ end
+
def snippet_file_count(snippet)
file_count = snippet.statistics&.file_count
diff --git a/app/helpers/sorting_helper.rb b/app/helpers/sorting_helper.rb
index 43ec02b6537..6f15cc7f4ec 100644
--- a/app/helpers/sorting_helper.rb
+++ b/app/helpers/sorting_helper.rb
@@ -267,6 +267,10 @@ module SortingHelper
options.concat([title_option])
end
+ def can_sort_by_issue_weight?(_viewing_issues)
+ false
+ 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
diff --git a/app/helpers/storage_helper.rb b/app/helpers/storage_helper.rb
index cb1a5f5ce0c..38ae9b5b634 100644
--- a/app/helpers/storage_helper.rb
+++ b/app/helpers/storage_helper.rb
@@ -25,20 +25,22 @@ 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)
+ root_ancestor = namespace.root_ancestor
+
+ return unless can?(current_user, :admin_namespace, root_ancestor)
+ return if root_ancestor.paid?
+ return unless future_enforcement_date?(root_ancestor)
+ return if user_dismissed_storage_enforcement_banner?(root_ancestor)
{
text: html_escape_once(s_("UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. " \
"You are currently using %{used_storage} of namespace storage. " \
"View and manage your usage from %{strong_start}%{namespace_type} settings &gt; 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 },
+ { storage_enforcement_date: root_ancestor.storage_enforcement_date, used_storage: storage_counter(root_ancestor.root_storage_statistics&.storage_size || 0), strong_start: "<strong>".html_safe, strong_end: "</strong>".html_safe, namespace_type: root_ancestor.type },
variant: 'warning',
- 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
+ callouts_path: root_ancestor.user_namespace? ? callouts_path : group_callouts_path,
+ callouts_feature_name: storage_enforcement_banner_user_callouts_feature_name(root_ancestor),
+ learn_more_link: link_to(_('Learn more.'), help_page_path('/'), rel: 'noopener noreferrer', target: '_blank')
}
end
@@ -63,8 +65,16 @@ module StorageHelper
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)
+ current_user.dismissed_callout_for_group?(
+ feature_name: storage_enforcement_banner_user_callouts_feature_name(namespace),
+ group: namespace
+ )
end
end
+
+ def future_enforcement_date?(namespace)
+ return true if ::Feature.enabled?(:namespace_storage_limit_bypass_date_check, namespace)
+
+ namespace.storage_enforcement_date.present? && namespace.storage_enforcement_date >= Date.today
+ end
end
diff --git a/app/helpers/system_note_helper.rb b/app/helpers/system_note_helper.rb
index 82847534d8e..5ab70115f34 100644
--- a/app/helpers/system_note_helper.rb
+++ b/app/helpers/system_note_helper.rb
@@ -6,7 +6,7 @@ module SystemNoteHelper
'unapproved' => 'unapproval',
'cherry_pick' => 'cherry-pick-commit',
'commit' => 'commit',
- 'description' => 'pencil-square',
+ 'description' => 'pencil',
'merge' => 'git-merge',
'merged' => 'git-merge',
'opened' => 'issues',
@@ -14,7 +14,7 @@ module SystemNoteHelper
'time_tracking' => 'timer',
'assignee' => 'user',
'reviewer' => 'user',
- 'title' => 'pencil-square',
+ 'title' => 'pencil',
'task' => 'task-done',
'label' => 'label',
'cross_reference' => 'comment-dots',
@@ -24,7 +24,7 @@ module SystemNoteHelper
'milestone' => 'clock',
'discussion' => 'comment',
'moved' => 'arrow-right',
- 'outdated' => 'pencil-square',
+ 'outdated' => 'pencil',
'pinned_embed' => 'thumbtack',
'duplicate' => 'duplicate',
'locked' => 'lock',
@@ -40,7 +40,7 @@ module SystemNoteHelper
'new_alert_added' => 'warning',
'severity' => 'information-o',
'cloned' => 'documents',
- 'issue_type' => 'pencil-square',
+ 'issue_type' => 'pencil',
'attention_requested' => 'user',
'attention_request_removed' => 'user',
'contact' => 'users',
diff --git a/app/helpers/tags_helper.rb b/app/helpers/tags_helper.rb
index 8216144c04c..665f7e0ddce 100644
--- a/app/helpers/tags_helper.rb
+++ b/app/helpers/tags_helper.rb
@@ -22,13 +22,4 @@ module TagsHelper
text.html_safe
end
-
- def delete_tag_modal_attributes(tag_name)
- {
- title: s_('TagsPage|Delete tag'),
- message: s_('TagsPage|Deleting the %{tag_name} tag cannot be undone. Are you sure?') % { tag_name: tag_name },
- okVariant: 'danger',
- okTitle: s_('TagsPage|Delete tag')
- }.to_json
- end
end
diff --git a/app/helpers/todos_helper.rb b/app/helpers/todos_helper.rb
index d3cc922423d..8529959f73c 100644
--- a/app/helpers/todos_helper.rb
+++ b/app/helpers/todos_helper.rb
@@ -100,17 +100,22 @@ module TodosHelper
def todo_target_state_pill(todo)
return unless show_todo_state?(todo)
- type =
- case todo.target
- when MergeRequest
- 'mr'
- when Issue
- 'issue'
- when AlertManagement::Alert
- 'alert'
+ state = todo.target.state.to_s
+
+ case todo.target
+ when MergeRequest
+ if state == 'closed'
+ background_class = 'gl-bg-red-500'
+ elsif state == 'merged'
+ background_class = 'gl-bg-blue-500'
end
+ when Issue
+ background_class = 'gl-bg-blue-500' if state == 'closed'
+ when AlertManagement::Alert
+ background_class = 'gl-bg-blue-500' if state == 'resolved'
+ end
- tag.span class: "gl-my-0 gl-px-2 status-box status-box-#{type}-#{todo.target.state.to_s.dasherize}" do
+ tag.span class: "gl-my-0 gl-px-2 status-box #{background_class}" do
todo.target.state.to_s.capitalize
end
end
diff --git a/app/helpers/tooling/visual_review_helper.rb b/app/helpers/tooling/visual_review_helper.rb
new file mode 100644
index 00000000000..da6eb3ec434
--- /dev/null
+++ b/app/helpers/tooling/visual_review_helper.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+module Tooling
+ module VisualReviewHelper
+ # Since we only use the visual review toolbar for the gitlab project,
+ # we can hardcode the project ID and project path for now.
+ #
+ # If we need to extend the review apps to other applications in the future,
+ # we should create REVIEW_APPS_PROJECT_ID and REVIEW_APPS_PROJECT_PATH
+ # environment variables (mapped to CI_PROJECT_ID and CI_PROJECT_PATH respectively),
+ # as well as setting `data-require-auth` according to the project visibility.
+ GITLAB_INSTANCE_URL = 'https://gitlab.com'
+ GITLAB_ORG_GITLAB_PROJECT_ID = '278964'
+ GITLAB_ORG_GITLAB_PROJECT_PATH = 'gitlab-org/gitlab'
+
+ def visual_review_toolbar_options
+ { 'data-merge-request-id': "#{ENV['REVIEW_APPS_MERGE_REQUEST_IID']}",
+ 'data-mr-url': "#{GITLAB_INSTANCE_URL}",
+ 'data-project-id': "#{GITLAB_ORG_GITLAB_PROJECT_ID}",
+ 'data-project-path': "#{GITLAB_ORG_GITLAB_PROJECT_PATH}",
+ 'data-require-auth': false,
+ 'id': 'review-app-toolbar-script',
+ 'src': 'https://gitlab.com/assets/webpack/visual_review_toolbar.js' }
+ end
+ end
+end
diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb
index fd460d71867..e46aa6a446c 100644
--- a/app/helpers/users_helper.rb
+++ b/app/helpers/users_helper.rb
@@ -140,7 +140,7 @@ module UsersHelper
messageHtml: message,
actionPrimary: {
text: s_('AdminUsers|Confirm user'),
- attributes: [{ variant: 'info', 'data-qa-selector': 'confirm_user_confirm_button' }]
+ attributes: [{ variant: 'confirm', 'data-qa-selector': 'confirm_user_confirm_button' }]
},
actionSecondary: {
text: _('Cancel'),
diff --git a/app/helpers/work_items_helper.rb b/app/helpers/work_items_helper.rb
new file mode 100644
index 00000000000..2c61fc20ca8
--- /dev/null
+++ b/app/helpers/work_items_helper.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+module WorkItemsHelper
+ def work_items_index_data(project)
+ {
+ full_path: project.full_path,
+ issues_list_path: project_issues_path(project)
+ }
+ end
+end