Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/helpers')
-rw-r--r--app/helpers/admin/abuse_reports_helper.rb3
-rw-r--r--app/helpers/application_helper.rb12
-rw-r--r--app/helpers/application_settings_helper.rb6
-rw-r--r--app/helpers/artifacts_helper.rb3
-rw-r--r--app/helpers/auth_helper.rb9
-rw-r--r--app/helpers/button_helper.rb68
-rw-r--r--app/helpers/ci/status_helper.rb72
-rw-r--r--app/helpers/ci/variables_helper.rb4
-rw-r--r--app/helpers/clusters_helper.rb2
-rw-r--r--app/helpers/colors_helper.rb2
-rw-r--r--app/helpers/diff_helper.rb2
-rw-r--r--app/helpers/emails_helper.rb2
-rw-r--r--app/helpers/environment_helper.rb2
-rw-r--r--app/helpers/environments_helper.rb7
-rw-r--r--app/helpers/external_link_helper.rb2
-rw-r--r--app/helpers/icons_helper.rb74
-rw-r--r--app/helpers/integrations_helper.rb23
-rw-r--r--app/helpers/invite_members_helper.rb25
-rw-r--r--app/helpers/issuables_helper.rb237
-rw-r--r--app/helpers/issues_helper.rb30
-rw-r--r--app/helpers/labels_helper.rb10
-rw-r--r--app/helpers/markup_helper.rb6
-rw-r--r--app/helpers/members_helper.rb8
-rw-r--r--app/helpers/merge_requests_helper.rb9
-rw-r--r--app/helpers/nav/new_dropdown_helper.rb2
-rw-r--r--app/helpers/nav_helper.rb4
-rw-r--r--app/helpers/organizations/organization_helper.rb34
-rw-r--r--app/helpers/profiles_helper.rb2
-rw-r--r--app/helpers/projects/observability_helper.rb23
-rw-r--r--app/helpers/projects/pipeline_helper.rb2
-rw-r--r--app/helpers/projects_helper.rb8
-rw-r--r--app/helpers/registrations_helper.rb2
-rw-r--r--app/helpers/routing/projects_helper.rb13
-rw-r--r--app/helpers/safe_format_helper.rb2
-rw-r--r--app/helpers/search_helper.rb8
-rw-r--r--app/helpers/sidebars_helper.rb99
-rw-r--r--app/helpers/sidekiq_helper.rb2
-rw-r--r--app/helpers/stat_anchors_helper.rb2
-rw-r--r--app/helpers/todos_helper.rb4
-rw-r--r--app/helpers/users/callouts_helper.rb7
-rw-r--r--app/helpers/users_helper.rb4
-rw-r--r--app/helpers/version_check_helper.rb3
-rw-r--r--app/helpers/vite_helper.rb29
-rw-r--r--app/helpers/webpack_helper.rb10
-rw-r--r--app/helpers/work_items_helper.rb6
45 files changed, 458 insertions, 426 deletions
diff --git a/app/helpers/admin/abuse_reports_helper.rb b/app/helpers/admin/abuse_reports_helper.rb
index 275bed406f1..015d4513091 100644
--- a/app/helpers/admin/abuse_reports_helper.rb
+++ b/app/helpers/admin/abuse_reports_helper.rb
@@ -18,7 +18,8 @@ module Admin
def abuse_report_data(report)
{
- abuse_report_data: Admin::AbuseReportDetailsSerializer.new.represent(report).to_json
+ abuse_report_data: Admin::AbuseReportDetailsSerializer.new.represent(report).to_json,
+ abuse_reports_list_path: admin_abuse_reports_path
}
end
end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 2bf239979f7..e3a630024d9 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -315,7 +315,8 @@ module ApplicationHelper
class_names << 'issue-boards-page gl-overflow-auto' if current_controller?(:boards)
class_names << 'epic-boards-page gl-overflow-auto' if current_controller?(:epic_boards)
class_names << 'with-performance-bar' if performance_bar_enabled?
- class_names << 'with-top-bar' if show_super_sidebar? && !@hide_top_bar
+ class_names << 'with-header' if !show_super_sidebar? || !current_user
+ class_names << 'with-top-bar' if show_super_sidebar? && !@hide_top_bar_padding
class_names << system_message_class
class_names << 'logged-out-marketing-header' if !current_user && ::Gitlab.com? && !show_super_sidebar?
@@ -485,6 +486,15 @@ module ApplicationHelper
end
end
+ def controller_full_path
+ action = case controller.action_name
+ when 'create' then 'new'
+ when 'update' then 'edit'
+ else controller.action_name
+ end
+ "#{controller.controller_path}/#{action}"
+ end
+
private
def browser_id
diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb
index a45425474b5..ef91915ce38 100644
--- a/app/helpers/application_settings_helper.rb
+++ b/app/helpers/application_settings_helper.rb
@@ -238,6 +238,7 @@ module ApplicationSettingsHelper
:container_expiration_policies_enable_historic_entries,
:container_registry_expiration_policies_caching,
:container_registry_token_expire_delay,
+ :decompress_archive_file_timeout,
:default_artifacts_expire_in,
:default_branch_name,
:default_branch_protection,
@@ -306,7 +307,6 @@ module ApplicationSettingsHelper
:housekeeping_optimize_repository_period,
:html_emails_enabled,
:import_sources,
- :in_product_marketing_emails_enabled,
:inactive_projects_delete_after_months,
:inactive_projects_min_size_mb,
:inactive_projects_send_warning_email_after_months,
@@ -413,6 +413,7 @@ module ApplicationSettingsHelper
:throttle_protected_paths_period_in_seconds,
:throttle_protected_paths_requests_per_period,
:protected_paths_raw,
+ :protected_paths_for_get_request_raw,
:time_tracking_limit_to_hours,
:two_factor_grace_period,
:update_runner_versions_enabled,
@@ -436,6 +437,7 @@ module ApplicationSettingsHelper
:mailgun_events_enabled,
:snowplow_collector_hostname,
:snowplow_cookie_domain,
+ :snowplow_database_collector_hostname,
:snowplow_enabled,
:snowplow_app_id,
:push_event_hooks_limit,
@@ -478,12 +480,14 @@ module ApplicationSettingsHelper
:sentry_dsn,
:sentry_clientside_dsn,
:sentry_environment,
+ :sentry_clientside_traces_sample_rate,
:sidekiq_job_limiter_mode,
:sidekiq_job_limiter_compression_threshold_bytes,
:sidekiq_job_limiter_limit_bytes,
:suggest_pipeline_enabled,
:search_rate_limit,
:search_rate_limit_unauthenticated,
+ :search_rate_limit_allowlist_raw,
:users_get_by_id_limit,
:users_get_by_id_limit_allowlist_raw,
:runner_token_expiration_interval,
diff --git a/app/helpers/artifacts_helper.rb b/app/helpers/artifacts_helper.rb
index f90d59409ed..10d2714840d 100644
--- a/app/helpers/artifacts_helper.rb
+++ b/app/helpers/artifacts_helper.rb
@@ -5,8 +5,7 @@ module ArtifactsHelper
{
project_path: project.full_path,
project_id: project.id,
- can_destroy_artifacts: can?(current_user, :destroy_artifacts, project).to_s,
- artifacts_management_feedback_image_path: image_path('illustrations/chat-bubble-sm.svg')
+ can_destroy_artifacts: can?(current_user, :destroy_artifacts, project).to_s
}
end
end
diff --git a/app/helpers/auth_helper.rb b/app/helpers/auth_helper.rb
index c928c6479de..b7acc562be5 100644
--- a/app/helpers/auth_helper.rb
+++ b/app/helpers/auth_helper.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module AuthHelper
- PROVIDERS_WITH_ICONS = %w(
+ PROVIDERS_WITH_ICONS = %w[
alicloud
atlassian_oauth2
auth0
@@ -15,12 +15,11 @@ module AuthHelper
google_oauth2
jwt
openid_connect
- salesforce
shibboleth
twitter
- ).freeze
- LDAP_PROVIDER = /\Aldap/.freeze
- POPULAR_PROVIDERS = %w(google_oauth2 github).freeze
+ ].freeze
+ LDAP_PROVIDER = /\Aldap/
+ POPULAR_PROVIDERS = %w[google_oauth2 github].freeze
delegate :slack_app_id, to: :'Gitlab::CurrentSettings.current_application_settings'
diff --git a/app/helpers/button_helper.rb b/app/helpers/button_helper.rb
index 6e0ba748d85..e6212ee7d8d 100644
--- a/app/helpers/button_helper.rb
+++ b/app/helpers/button_helper.rb
@@ -7,6 +7,15 @@ module ButtonHelper
# :text - Text to copy (optional)
# :gfm - GitLab Flavored Markdown to copy, if different from `text` (optional)
# :target - Selector for target element to copy from (optional)
+ # :class - CSS classes to be applied to the button (optional)
+ # :title - Button's title attribute (used for the tooltip) (optional)
+ # :button_text - Button's displayed label (optional)
+ # :hide_tooltip - Whether the tooltip should be hidden (optional, default: false)
+ # :hide_button_icon - Whether the icon should be hidden (optional, default: false)
+ # :item_prop - itemprop attribute
+ # :variant - Button variant (optional, default: :default)
+ # :category - Button category (optional, default: :tertiary)
+ # :size - Button size (optional, default: :small)
#
# Examples:
#
@@ -20,6 +29,65 @@ module ButtonHelper
#
# See http://clipboardjs.com/#usage
def clipboard_button(data = {})
+ css_class = data.delete(:class)
+ title = data.delete(:title) || _('Copy')
+ button_text = data[:button_text] || nil
+ hide_tooltip = data[:hide_tooltip] || false
+ hide_button_icon = data[:hide_button_icon] || false
+ item_prop = data[:itemprop] || nil
+ variant = data[:variant] || :default
+ category = data[:category] || :tertiary
+ size = data[:size] || :small
+
+ # This supports code in app/assets/javascripts/copy_to_clipboard.js that
+ # works around ClipboardJS limitations to allow the context-specific copy/pasting of plain text or GFM.
+ if text = data.delete(:text)
+ data[:clipboard_text] =
+ if gfm = data.delete(:gfm)
+ { text: text, gfm: gfm }
+ else
+ text
+ end
+ end
+
+ target = data.delete(:target)
+ data[:clipboard_target] = target if target
+
+ unless hide_tooltip
+ data = { toggle: 'tooltip', placement: 'bottom', container: 'body' }.merge(data)
+ end
+
+ render ::Pajamas::ButtonComponent.new(
+ icon: hide_button_icon ? nil : 'copy-to-clipboard',
+ variant: variant,
+ category: category,
+ size: size,
+ button_options: { class: css_class, title: title, aria: { label: title, live: 'polite' }, data: data, itemprop: item_prop }) do
+ button_text
+ end
+ end
+
+ # Output a "Copy to Clipboard" button
+ # Note: This is being replaced by a Pajamas-compliant helper that renders the button
+ # via ::Pajamas::ButtonComponent. Please use clipboard_button instead.
+ #
+ # data - Data attributes passed to `content_tag` (default: {}):
+ # :text - Text to copy (optional)
+ # :gfm - GitLab Flavored Markdown to copy, if different from `text` (optional)
+ # :target - Selector for target element to copy from (optional)
+ #
+ # Examples:
+ #
+ # # Define the clipboard's text
+ # clipboard_button(text: "Foo")
+ # # => "<button class='...' data-clipboard-text='Foo'>...</button>"
+ #
+ # # Define the target element
+ # clipboard_button(target: "div#foo")
+ # # => "<button class='...' data-clipboard-target='div#foo'>...</button>"
+ #
+ # See http://clipboardjs.com/#usage
+ def deprecated_clipboard_button(data = {})
css_class = data.delete(:class) || 'btn-clipboard gl-button btn-default-tertiary btn-icon btn-sm'
title = data.delete(:title) || _('Copy')
button_text = data[:button_text] || nil
diff --git a/app/helpers/ci/status_helper.rb b/app/helpers/ci/status_helper.rb
index ea5b613cb78..5d526a6abb6 100644
--- a/app/helpers/ci/status_helper.rb
+++ b/app/helpers/ci/status_helper.rb
@@ -9,55 +9,6 @@
#
module Ci
module StatusHelper
- def ci_label_for_status(status)
- if detailed_status?(status)
- return status.label
- end
-
- label = case status
- when 'success'
- 'passed'
- when 'success-with-warnings'
- 'passed with warnings'
- when 'manual'
- 'waiting for manual action'
- when 'scheduled'
- 'waiting for delayed job'
- else
- status
- end
- translation = "CiStatusLabel|#{label}"
- s_(translation)
- end
-
- def ci_text_for_status(status)
- if detailed_status?(status)
- return status.text
- end
-
- case status
- when 'success'
- s_('CiStatusText|passed')
- when 'success-with-warnings'
- s_('CiStatusText|passed')
- when 'manual'
- s_('CiStatusText|blocked')
- when 'scheduled'
- s_('CiStatusText|delayed')
- else
- # All states are already being translated inside the detailed statuses:
- # :running => Gitlab::Ci::Status::Running
- # :skipped => Gitlab::Ci::Status::Skipped
- # :failed => Gitlab::Ci::Status::Failed
- # :success => Gitlab::Ci::Status::Success
- # :canceled => Gitlab::Ci::Status::Canceled
- # The following states are customized above:
- # :manual => Gitlab::Ci::Status::Manual
- status_translation = "CiStatusText|#{status}"
- s_(status_translation)
- end
- end
-
def ci_status_for_statuseable(subject)
status = subject.try(:status) || 'not found'
status.humanize
@@ -138,11 +89,34 @@ module Ci
end
end
+ private
+
def detailed_status?(status)
status.respond_to?(:text) &&
status.respond_to?(:group) &&
status.respond_to?(:label) &&
status.respond_to?(:icon)
end
+
+ def ci_label_for_status(status)
+ if detailed_status?(status)
+ return status.label
+ end
+
+ label = case status
+ when 'success'
+ 'passed'
+ when 'success-with-warnings'
+ 'passed with warnings'
+ when 'manual'
+ 'waiting for manual action'
+ when 'scheduled'
+ 'waiting for delayed job'
+ else
+ status
+ end
+ translation = "CiStatusLabel|#{label}"
+ s_(translation)
+ end
end
end
diff --git a/app/helpers/ci/variables_helper.rb b/app/helpers/ci/variables_helper.rb
index a492c48e58c..0dbd1adeb71 100644
--- a/app/helpers/ci/variables_helper.rb
+++ b/app/helpers/ci/variables_helper.rb
@@ -42,8 +42,8 @@ module Ci
def ci_variable_type_options
[
- %w(Variable env_var),
- %w(File file)
+ %w[Variable env_var],
+ %w[File file]
]
end
diff --git a/app/helpers/clusters_helper.rb b/app/helpers/clusters_helper.rb
index 5c410a28229..1989d6ab3d5 100644
--- a/app/helpers/clusters_helper.rb
+++ b/app/helpers/clusters_helper.rb
@@ -92,7 +92,7 @@ module ClustersHelper
end
def cluster_created?(cluster)
- !cluster.status_name.in?(%i/scheduled creating/)
+ !cluster.status_name.in?(%i[scheduled creating])
end
def can_admin_cluster?(user, cluster)
diff --git a/app/helpers/colors_helper.rb b/app/helpers/colors_helper.rb
index 80cf6f197e5..3cd7263c39e 100644
--- a/app/helpers/colors_helper.rb
+++ b/app/helpers/colors_helper.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module ColorsHelper
- HEX_COLOR_PATTERN = /\A\#(?:[0-9A-Fa-f]{3}){1,2}\Z/.freeze
+ HEX_COLOR_PATTERN = /\A\#(?:[0-9A-Fa-f]{3}){1,2}\Z/
def hex_color_to_rgb_array(hex_color)
unless hex_color.is_a?(String) && HEX_COLOR_PATTERN.match?(hex_color)
diff --git a/app/helpers/diff_helper.rb b/app/helpers/diff_helper.rb
index c5df53ec606..9a78d4d9ad5 100644
--- a/app/helpers/diff_helper.rb
+++ b/app/helpers/diff_helper.rb
@@ -16,7 +16,7 @@ module DiffHelper
def diff_view
@diff_view ||= begin
- diff_views = %w(inline parallel)
+ diff_views = %w[inline parallel]
diff_view = params[:view] || cookies[:diff_view]
diff_view = diff_views.first unless diff_views.include?(diff_view)
diff_view.to_sym
diff --git a/app/helpers/emails_helper.rb b/app/helpers/emails_helper.rb
index af0f1bd6808..69b3fdc2271 100644
--- a/app/helpers/emails_helper.rb
+++ b/app/helpers/emails_helper.rb
@@ -16,7 +16,7 @@ module EmailsHelper
def action_title(url)
return unless url
- %w(merge_requests issues commit).each do |action|
+ %w[merge_requests issues commit].each do |action|
if url.split("/").include?(action)
return "View #{action.humanize.singularize}"
end
diff --git a/app/helpers/environment_helper.rb b/app/helpers/environment_helper.rb
index 8140ee97291..6e9379a5926 100644
--- a/app/helpers/environment_helper.rb
+++ b/app/helpers/environment_helper.rb
@@ -62,7 +62,7 @@ module EnvironmentHelper
klass = "ci-status ci-#{status.dasherize} #{ci_icon_utilities}"
text = "#{ci_icon_for_status(status)} <span class=\"gl-ml-2\">#{status_text}</span>".html_safe
- if deployment.deployable
+ if deployment.deployable.instance_of?(::Ci::Build)
link_to(text, deployment_path(deployment), class: klass)
else
content_tag(:span, text, class: klass)
diff --git a/app/helpers/environments_helper.rb b/app/helpers/environments_helper.rb
index cd768ba8a7b..80a56493653 100644
--- a/app/helpers/environments_helper.rb
+++ b/app/helpers/environments_helper.rb
@@ -57,11 +57,9 @@ module EnvironmentsHelper
'default_branch' => project.default_branch,
'project_path' => project_path(project),
'tags_path' => project_tags_path(project),
- 'external_dashboard_url' => project.metrics_setting_external_dashboard_url,
'custom_metrics_path' => project_prometheus_metrics_path(project),
'validate_query_path' => validate_query_project_prometheus_metrics_path(project),
- 'custom_metrics_available' => custom_metrics_available?(project).to_s,
- 'dashboard_timezone' => project.metrics_setting_dashboard_timezone.to_s.upcase
+ 'custom_metrics_available' => custom_metrics_available?(project).to_s
}
end
@@ -93,8 +91,7 @@ module EnvironmentsHelper
'empty_loading_svg_path' => image_path('illustrations/monitoring/loading.svg'),
'empty_no_data_svg_path' => image_path('illustrations/monitoring/no_data.svg'),
'empty_no_data_small_svg_path' => image_path('illustrations/chart-empty-state-small.svg'),
- 'empty_unable_to_connect_svg_path' => image_path('illustrations/monitoring/unable_to_connect.svg'),
- 'custom_dashboard_base_path' => Gitlab::Metrics::Dashboard::RepoDashboardFinder::DASHBOARD_ROOT
+ 'empty_unable_to_connect_svg_path' => image_path('illustrations/monitoring/unable_to_connect.svg')
}
end
end
diff --git a/app/helpers/external_link_helper.rb b/app/helpers/external_link_helper.rb
index 53dacfe0566..40079c0803d 100644
--- a/app/helpers/external_link_helper.rb
+++ b/app/helpers/external_link_helper.rb
@@ -7,6 +7,6 @@ module ExternalLinkHelper
link = link_to url, { target: '_blank', rel: 'noopener noreferrer' }.merge(options) do
"#{body}#{sprite_icon('external-link', css_class: 'gl-ml-2')}".html_safe
end
- sanitize(link, tags: %w(a svg use), attributes: %w(target rel data-testid class href).concat(options.stringify_keys.keys))
+ sanitize(link, tags: %w[a svg use], attributes: %w[target rel data-testid class href].concat(options.stringify_keys.keys))
end
end
diff --git a/app/helpers/icons_helper.rb b/app/helpers/icons_helper.rb
index bba3fac7468..ebebdfa56e6 100644
--- a/app/helpers/icons_helper.rb
+++ b/app/helpers/icons_helper.rb
@@ -29,9 +29,10 @@ module IconsHelper
ActionController::Base.helpers.image_path('file_icons/file_icons.svg', host: sprite_base_url)
end
- def sprite_icon(icon_name, size: DEFAULT_ICON_SIZE, css_class: nil)
+ def sprite_icon(icon_name, size: DEFAULT_ICON_SIZE, css_class: nil, file_icon: false)
memoized_icon("#{icon_name}_#{size}_#{css_class}") do
- if known_sprites&.exclude?(icon_name)
+ unknown_icon = file_icon ? unknown_file_icon_sprite(icon_name) : unknown_icon_sprite(icon_name)
+ if unknown_icon
exception = ArgumentError.new("#{icon_name} is not a known icon in @gitlab-org/gitlab-svg")
Gitlab::ErrorTracking.track_and_raise_for_dev_exception(exception)
end
@@ -39,10 +40,11 @@ module IconsHelper
css_classes = []
css_classes << "s#{size}" if size
css_classes << css_class.to_s unless css_class.blank?
+ sprite_path = file_icon ? sprite_file_icons_path : sprite_icon_path
content_tag(
:svg,
- content_tag(:use, '', { 'href' => "#{sprite_icon_path}##{icon_name}" }),
+ content_tag(:use, '', { 'href' => "#{sprite_path}##{icon_name}" }),
class: css_classes.empty? ? nil : css_classes.join(' '),
data: { testid: "#{icon_name}-icon" }
)
@@ -123,61 +125,73 @@ module IconsHelper
def file_type_icon_class(type, mode, name)
if type == 'folder'
- icon_class = 'folder-o'
+ 'folder-o'
elsif type == 'archive'
- icon_class = 'archive'
+ 'archive'
elsif mode == '120000'
- icon_class = 'share'
+ 'share'
else
# Guess which icon to choose based on file extension.
# If you think a file extension is missing, feel free to add it on PR
case File.extname(name).downcase
when '.pdf'
- icon_class = 'document'
+ 'document'
when '.jpg', '.jpeg', '.jif', '.jfif',
- '.jp2', '.jpx', '.j2k', '.j2c',
- '.apng', '.png', '.gif', '.tif', '.tiff',
- '.svg', '.ico', '.bmp', '.webp'
- icon_class = 'doc-image'
+ '.jp2', '.jpx', '.j2k', '.j2c',
+ '.apng', '.png', '.gif', '.tif', '.tiff',
+ '.svg', '.ico', '.bmp', '.webp'
+ 'doc-image'
when '.zip', '.zipx', '.tar', '.gz', '.gzip', '.tgz', '.bz', '.bzip',
- '.bz2', '.bzip2', '.car', '.tbz', '.xz', 'txz', '.rar', '.7z',
- '.lz', '.lzma', '.tlz'
- icon_class = 'doc-compressed'
+ '.bz2', '.bzip2', '.car', '.tbz', '.xz', 'txz', '.rar', '.7z',
+ '.lz', '.lzma', '.tlz'
+ 'doc-compressed'
when '.mp3', '.wma', '.ogg', '.oga', '.wav', '.flac', '.aac', '.3ga',
- '.ac3', '.midi', '.m4a', '.ape', '.mpa'
- icon_class = 'volume-up'
+ '.ac3', '.midi', '.m4a', '.ape', '.mpa'
+ 'volume-up'
when '.mp4', '.m4p', '.m4v',
- '.mpg', '.mp2', '.mpeg', '.mpe', '.mpv',
- '.mpg', '.mpeg', '.m2v', '.m2ts',
- '.avi', '.mkv', '.flv', '.ogv', '.mov',
- '.3gp', '.3g2'
- icon_class = 'live-preview'
+ '.mpg', '.mp2', '.mpeg', '.mpe', '.mpv',
+ '.mpg', '.mpeg', '.m2v', '.m2ts',
+ '.avi', '.mkv', '.flv', '.ogv', '.mov',
+ '.3gp', '.3g2'
+ 'live-preview'
when '.doc', '.dot', '.docx', '.docm', '.dotx', '.dotm', '.docb',
- '.odt', '.ott', '.uot', '.rtf'
- icon_class = 'doc-text'
+ '.odt', '.ott', '.uot', '.rtf'
+ 'doc-text'
when '.xls', '.xlt', '.xlm', '.xlsx', '.xlsm', '.xltx', '.xltm',
- '.xlsb', '.xla', '.xlam', '.xll', '.xlw', '.ots', '.ods', '.uos'
- icon_class = 'document'
+ '.xlsb', '.xla', '.xlam', '.xll', '.xlw', '.ots', '.ods', '.uos'
+ 'document'
when '.ppt', '.pot', '.pps', '.pptx', '.pptm', '.potx', '.potm',
- '.ppam', '.ppsx', '.ppsm', '.sldx', '.sldm', '.odp', '.otp', '.uop'
- icon_class = 'doc-chart'
+ '.ppam', '.ppsx', '.ppsm', '.sldx', '.sldm', '.odp', '.otp', '.uop'
+ 'doc-chart'
else
- icon_class = 'doc-text'
+ 'doc-text'
end
end
-
- icon_class
end
private
+ def unknown_icon_sprite(icon_name)
+ known_sprites&.exclude?(icon_name)
+ end
+
+ def unknown_file_icon_sprite(icon_name)
+ known_file_icon_sprites&.exclude?(icon_name)
+ end
+
def known_sprites
return if Rails.env.production?
@known_sprites ||= Gitlab::Json.parse(File.read(Rails.root.join('node_modules/@gitlab/svgs/dist/icons.json')))['icons']
end
+ def known_file_icon_sprites
+ return if Rails.env.production?
+
+ @known_file_icon_sprites ||= Gitlab::Json.parse(File.read(Rails.root.join('node_modules/@gitlab/svgs/dist/file_icons/file_icons.json')))['icons']
+ end
+
def memoized_icon(key)
@rendered_icons ||= {}
diff --git a/app/helpers/integrations_helper.rb b/app/helpers/integrations_helper.rb
index 645a08bfcc0..a88be976337 100644
--- a/app/helpers/integrations_helper.rb
+++ b/app/helpers/integrations_helper.rb
@@ -277,11 +277,11 @@ module IntegrationsHelper
s_("ProjectService|Trigger event for new comments.")
when "confidential_note", "confidential_note_events"
s_("ProjectService|Trigger event for new comments on confidential issues.")
- when "issue", "issue_events"
+ when "issue", "issue_events", "issues_events"
s_("ProjectService|Trigger event when an issue is created, updated, or closed.")
- when "confidential_issue", "confidential_issue_events"
+ when "confidential_issue", "confidential_issue_events", "confidential_issues_events"
s_("ProjectService|Trigger event when a confidential issue is created, updated, or closed.")
- when "merge_request", "merge_request_events"
+ when "merge_request", "merge_request_events", "merge_requests_events"
s_("ProjectService|Trigger event when a merge request is created, updated, or merged.")
when "pipeline", "pipeline_events"
s_("ProjectService|Trigger event when a pipeline status changes.")
@@ -289,16 +289,20 @@ module IntegrationsHelper
s_("ProjectService|Trigger event when a wiki page is created or updated.")
when "commit", "commit_events"
s_("ProjectService|Trigger event when a commit is created or updated.")
- when "deployment"
+ when "deployment", "deployment_events"
s_("ProjectService|Trigger event when a deployment starts or finishes.")
- when "alert"
+ when "alert", "alert_events"
s_("ProjectService|Trigger event when a new, unique alert is recorded.")
- when "incident"
+ when "incident", "incident_events"
s_("ProjectService|Trigger event when an incident is created.")
when "group_mention"
s_("ProjectService|Trigger event when a group is mentioned in a public context.")
when "group_confidential_mention"
s_("ProjectService|Trigger event when a group is mentioned in a confidential context.")
+ when "build_events"
+ s_("ProjectService|Trigger event when a build is created.")
+ when "archive_trace_events"
+ s_('When enabled, job logs are collected by Datadog and displayed along with pipeline execution traces.')
end
end
# rubocop:enable Metrics/CyclomaticComplexity
@@ -323,12 +327,15 @@ module IntegrationsHelper
def serialize_integration(integration, group: nil, project: nil)
{
- active: integration.operating?,
+ id: integration.id,
+ active: integration.activated?,
+ configured: integration.persisted?,
title: integration.title,
description: integration.description,
updated_at: integration.updated_at,
edit_path: scoped_edit_integration_path(integration, group: group, project: project),
- name: integration.to_param
+ name: integration.to_param,
+ icon: integration.try(:avatar_url)
}
end
end
diff --git a/app/helpers/invite_members_helper.rb b/app/helpers/invite_members_helper.rb
index 422380f3cc6..0443861903b 100644
--- a/app/helpers/invite_members_helper.rb
+++ b/app/helpers/invite_members_helper.rb
@@ -37,23 +37,13 @@ module InviteMembersHelper
# Overridden in EE
def common_invite_modal_dataset(source)
- dataset = {
+ {
id: source.id,
root_id: source.root_ancestor&.id,
name: source.name,
default_access_level: Gitlab::Access::GUEST,
full_path: source.full_path
}
-
- if current_user && show_invite_members_for_task?
- dataset.merge!(
- tasks_to_be_done_options: tasks_to_be_done_options.to_json,
- projects: projects_for_source(source).to_json,
- new_project_path: source.is_a?(Group) ? new_project_path(namespace_id: source.id) : ''
- )
- end
-
- dataset
end
private
@@ -70,19 +60,6 @@ module InviteMembersHelper
def users_filter_data(group)
{}
end
-
- def show_invite_members_for_task?
- params[:open_modal] == 'invite_members_for_task'
- end
-
- def tasks_to_be_done_options
- ::MemberTask::TASKS.keys.map { |task| { value: task, text: localized_tasks_to_be_done_choices[task] } }
- end
-
- def projects_for_source(source)
- projects = source.is_a?(Project) ? [source] : source.projects
- projects.map { |project| { id: project.id, title: project.title } }
- end
end
InviteMembersHelper.prepend_mod_with('InviteMembersHelper')
diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb
index c83545fa7a7..7f948db2f71 100644
--- a/app/helpers/issuables_helper.rb
+++ b/app/helpers/issuables_helper.rb
@@ -33,22 +33,6 @@ module IssuablesHelper
end
end
- def sidebar_milestone_tooltip_label(milestone)
- return _('Milestone') unless milestone.present?
-
- [escape_once(milestone[:title]), sidebar_milestone_remaining_days(milestone) || _('Milestone')].join('<br/>')
- end
-
- def sidebar_milestone_remaining_days(milestone)
- due_date_with_remaining_days(milestone[:due_date], milestone[:start_date])
- end
-
- def due_date_with_remaining_days(due_date, start_date = nil)
- return unless due_date
-
- "#{due_date.to_fs(:medium)} (#{remaining_days_in_words(due_date, start_date)})"
- end
-
def multi_label_name(current_labels, default_label)
return default_label if current_labels.blank?
@@ -131,46 +115,6 @@ module IssuablesHelper
end
# rubocop: enable CodeReuse/ActiveRecord
- def issuable_meta_author_status(author)
- return "" unless author&.status&.customized? && status = user_status(author)
-
- status.to_s.html_safe
- end
-
- def issuable_meta(issuable, project)
- output = []
-
- if issuable.respond_to?(:work_item_type) && WorkItems::Type::WI_TYPES_WITH_CREATED_HEADER.include?(issuable.issue_type)
- output << content_tag(:span, sprite_icon(issuable.work_item_type.icon_name.to_s, css_class: 'gl-icon gl-vertical-align-middle gl-text-gray-500'), class: 'gl-mr-2', aria: { hidden: 'true' })
- output << content_tag(:span, s_('IssuableStatus|%{wi_type} created %{created_at} by ').html_safe % { wi_type: IntegrationsHelper.integration_issue_type(issuable.issue_type), created_at: time_ago_with_tooltip(issuable.created_at) }, class: 'gl-mr-2')
- else
- output << content_tag(:span, s_('IssuableStatus|Created %{created_at} by').html_safe % { created_at: time_ago_with_tooltip(issuable.created_at) }, class: 'gl-mr-2')
- end
-
- if issuable.is_a?(Issue) && issuable.service_desk_reply_to
- output << "#{html_escape(issuable.present(current_user: current_user).service_desk_reply_to)} via "
- end
-
- output << content_tag(:strong) do
- author_output = link_to_member(project, issuable.author, size: 24, mobile_classes: "d-none d-sm-inline-block")
- author_output << link_to_member(project, issuable.author, size: 24, by_username: true, avatar: false, mobile_classes: "d-inline d-sm-none")
-
- author_output << issuable_meta_author_status(issuable.author)
-
- author_output
- end
-
- if access = project.team.human_max_access(issuable.author_id)
- output << content_tag(:span, access, class: "user-access-role has-tooltip d-none d-xl-inline-block gl-ml-3 ", title: _("This user has the %{access} role in the %{name} project.") % { access: access.downcase, name: project.name })
- elsif project.team.contributor?(issuable.author_id)
- output << content_tag(:span, _("Contributor"), class: "user-access-role has-tooltip d-none d-xl-inline-block gl-ml-3", title: _("This user has previously committed to the %{name} project.") % { name: project.name })
- end
-
- output << content_tag(:span, (sprite_icon('first-contribution', css_class: 'gl-icon gl-vertical-align-middle') if issuable.first_contribution?), class: 'has-tooltip gl-ml-2', title: _('1st contribution!'))
-
- output.join.html_safe
- end
-
def issuables_state_counter_text(issuable_type, state, display_count)
titles = {
opened: _("Open"),
@@ -248,71 +192,6 @@ module IssuablesHelper
data
end
- def issue_only_initial_data(issuable)
- return {} unless issuable.is_a?(Issue)
-
- data = {
- authorId: issuable.author.id,
- authorName: issuable.author.name,
- authorUsername: issuable.author.username,
- authorWebUrl: url_for(user_path(issuable.author)),
- createdAt: issuable.created_at.to_time.iso8601,
- hasClosingMergeRequest: issuable.merge_requests_count(current_user) != 0,
- isFirstContribution: issuable.first_contribution?,
- issueType: issuable.issue_type,
- serviceDeskReplyTo: issuable.present(current_user: current_user).service_desk_reply_to,
- zoomMeetingUrl: ZoomMeeting.canonical_meeting_url(issuable),
- sentryIssueIdentifier: SentryIssue.find_by(issue: issuable)&.sentry_issue_identifier, # rubocop:disable CodeReuse/ActiveRecord
- iid: issuable.iid.to_s,
- isHidden: issue_hidden?(issuable),
- canCreateIncident: create_issue_type_allowed?(issuable.project, :incident),
- **incident_only_initial_data(issuable)
- }
-
- data.tap do |d|
- if issuable.duplicated? && can?(current_user, :read_issue, issuable.duplicated_to)
- d[:duplicatedToIssueUrl] = url_for([issuable.duplicated_to.project, issuable.duplicated_to, { only_path: false }])
- end
-
- if issuable.moved? && can?(current_user, :read_issue, issuable.moved_to)
- d[:movedToIssueUrl] = url_for([issuable.moved_to.project, issuable.moved_to, { only_path: false }])
- end
- end
- end
-
- def incident_only_initial_data(issue)
- return {} unless issue.incident_type_issue?
-
- {
- hasLinkedAlerts: issue.alert_management_alerts.any?,
- canUpdateTimelineEvent: can?(current_user, :admin_incident_management_timeline_event, issue),
- currentPath: url_for(safe_params),
- currentTab: safe_params[:incident_tab]
- }
- end
-
- def path_data(parent)
- return { groupPath: parent.path } if parent.is_a?(Group)
-
- {
- projectPath: ref_project.path,
- projectId: ref_project.id,
- projectNamespace: ref_project.namespace.full_path
- }
- end
-
- def updated_at_by(issuable)
- return {} unless issuable.edited?
-
- {
- updatedAt: issuable.last_edited_at.to_time.iso8601,
- updatedBy: {
- name: issuable.last_edited_by.name,
- path: user_path(issuable.last_edited_by)
- }
- }
- end
-
def issuables_count_for_state(issuable_type, state)
Gitlab::IssuablesCountForState.new(finder, fast_fail: true, store_in_redis_cache: true)[state]
end
@@ -333,15 +212,6 @@ module IssuablesHelper
issuable.author == current_user
end
- def issuable_display_type(issuable)
- case issuable
- when Issue
- issuable.issue_type.downcase
- when MergeRequest
- issuable.model_name.human.downcase
- end
- end
-
def has_filter_bar_param?
finder.class.scalar_params.any? { |p| params[p].present? }
end
@@ -353,12 +223,6 @@ module IssuablesHelper
end
end
- def reviewer_sidebar_data(reviewer, merge_request: nil)
- { avatar_url: reviewer.avatar_url, name: reviewer.name, username: reviewer.username }.tap do |data|
- data[:can_merge] = merge_request.can_be_merged_by?(reviewer) if merge_request
- end
- end
-
def issuable_squash_option?(issuable, project)
if issuable.persisted?
issuable.squash
@@ -428,27 +292,6 @@ module IssuablesHelper
cookies[:collapsed_gutter] == 'true'
end
- def issuable_todo_button_data(issuable, is_collapsed)
- {
- todo_text: _('Add a to do'),
- mark_text: _('Mark as done'),
- todo_icon: sprite_icon('todo-add'),
- mark_icon: sprite_icon('todo-done', css_class: 'todo-undone'),
- issuable_id: issuable[:id],
- issuable_type: issuable[:type],
- create_path: issuable[:create_todo_path],
- delete_path: issuable.dig(:current_user, :todo, :delete_path),
- placement: is_collapsed ? 'left' : nil,
- container: is_collapsed ? 'body' : nil,
- boundary: 'viewport',
- is_collapsed: is_collapsed,
- track_label: "right_sidebar",
- track_property: "update_todo",
- track_action: "click_button",
- track_value: ""
- }
- end
-
def close_reopen_params(issuable, action)
{
issuable.model_name.to_s.underscore => { state_event: action }
@@ -520,6 +363,86 @@ module IssuablesHelper
number_with_delimiter(count)
end
end
+
+ def issue_only_initial_data(issuable)
+ return {} unless issuable.is_a?(Issue)
+
+ {
+ canCreateIncident: create_issue_type_allowed?(issuable.project, :incident),
+ fullPath: issuable.project.full_path,
+ iid: issuable.iid,
+ issuableId: issuable.id,
+ issueType: issuable.issue_type,
+ isHidden: issue_hidden?(issuable),
+ sentryIssueIdentifier: SentryIssue.find_by(issue: issuable)&.sentry_issue_identifier, # rubocop:disable CodeReuse/ActiveRecord
+ zoomMeetingUrl: ZoomMeeting.canonical_meeting_url(issuable),
+ **incident_only_initial_data(issuable),
+ **issue_header_data(issuable),
+ **work_items_data
+ }
+ end
+
+ def incident_only_initial_data(issue)
+ return {} unless issue.incident_type_issue?
+
+ {
+ hasLinkedAlerts: issue.alert_management_alerts.any?,
+ canUpdateTimelineEvent: can?(current_user, :admin_incident_management_timeline_event, issue),
+ currentPath: url_for(safe_params),
+ currentTab: safe_params[:incident_tab]
+ }
+ end
+
+ def issue_header_data(issuable)
+ data = {
+ authorId: issuable.author.id,
+ authorName: issuable.author.name,
+ authorUsername: issuable.author.username,
+ authorWebUrl: url_for(user_path(issuable.author)),
+ createdAt: issuable.created_at.to_time.iso8601,
+ isFirstContribution: issuable.first_contribution?,
+ serviceDeskReplyTo: issuable.present(current_user: current_user).service_desk_reply_to
+ }
+
+ data.tap do |d|
+ if issuable.duplicated? && can?(current_user, :read_issue, issuable.duplicated_to)
+ d[:duplicatedToIssueUrl] = url_for([issuable.duplicated_to.project, issuable.duplicated_to, { only_path: false }])
+ end
+
+ if issuable.moved? && can?(current_user, :read_issue, issuable.moved_to)
+ d[:movedToIssueUrl] = url_for([issuable.moved_to.project, issuable.moved_to, { only_path: false }])
+ end
+ end
+ end
+
+ def work_items_data
+ {
+ registerPath: new_user_registration_path(redirect_to_referer: 'yes'),
+ signInPath: new_session_path(:user, redirect_to_referer: 'yes')
+ }
+ end
+
+ def path_data(parent)
+ return { groupPath: parent.path } if parent.is_a?(Group)
+
+ {
+ projectPath: ref_project.path,
+ projectId: ref_project.id,
+ projectNamespace: ref_project.namespace.full_path
+ }
+ end
+
+ def updated_at_by(issuable)
+ return {} unless issuable.edited?
+
+ {
+ updatedAt: issuable.last_edited_at.to_time.iso8601,
+ updatedBy: {
+ name: issuable.last_edited_by.name,
+ path: user_path(issuable.last_edited_by)
+ }
+ }
+ end
end
IssuablesHelper.prepend_mod_with('IssuablesHelper')
diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb
index ed655b562c2..4419b573701 100644
--- a/app/helpers/issues_helper.rb
+++ b/app/helpers/issues_helper.rb
@@ -35,15 +35,6 @@ module IssuesHelper
end
end
- def issue_status_visibility(issue, status_box:)
- case status_box
- when :open
- 'hidden' if issue.closed?
- when :closed
- 'hidden' unless issue.closed?
- end
- end
-
def confidential_icon(issue)
sprite_icon('eye-slash', css_class: 'gl-vertical-align-text-bottom') if issue.confidential?
end
@@ -128,24 +119,6 @@ module IssuesHelper
can?(current_user, :create_merge_request_in, @project)
end
- def issue_closed_link(issue, current_user, css_class: '')
- if issue.moved? && can?(current_user, :read_issue, issue.moved_to)
- link_to(s_('IssuableStatus|moved'), issue.moved_to, class: css_class)
- elsif issue.duplicated? && can?(current_user, :read_issue, issue.duplicated_to)
- link_to(s_('IssuableStatus|duplicated'), issue.duplicated_to, class: css_class)
- end
- end
-
- def issue_closed_text(issue, current_user)
- link = issue_closed_link(issue, current_user, css_class: 'text-underline gl-reset-color!')
-
- if link
- s_('IssuableStatus|Closed (%{link})').html_safe % { link: link }
- else
- s_('IssuableStatus|Closed')
- end
- end
-
def show_moved_service_desk_issue_warning?(issue)
return false unless issue.moved_from
return false unless issue.from_service_desk?
@@ -167,11 +140,8 @@ module IssuesHelper
can_reopen_issue: can?(current_user, :reopen_issue, issuable).to_s,
can_report_spam: issuable.submittable_as_spam_by?(current_user).to_s,
can_update_issue: can?(current_user, :update_issue, issuable).to_s,
- iid: issuable.iid,
- issuable_id: issuable.id,
is_issue_author: (issuable.author == current_user).to_s,
issue_path: issuable_path(issuable),
- issue_type: issuable_display_type(issuable),
new_issue_path: new_project_issue_path(project, new_issuable_params),
project_path: project.full_path,
report_abuse_path: add_category_abuse_reports_path,
diff --git a/app/helpers/labels_helper.rb b/app/helpers/labels_helper.rb
index 79bab0969d1..a6bc9bcf205 100644
--- a/app/helpers/labels_helper.rb
+++ b/app/helpers/labels_helper.rb
@@ -68,7 +68,7 @@ module LabelsHelper
# We need the `label` argument here for EE
def wrap_label_html(label_html, small:, label:)
- wrapper_classes = %w(gl-label)
+ wrapper_classes = %w[gl-label]
wrapper_classes << 'gl-label-sm' if small
%(<span class="#{wrapper_classes.join(' ')}">#{label_html}</span>).html_safe
@@ -220,10 +220,16 @@ module LabelsHelper
project || group&.subgroup?
end
+ def label_lock_on_merge_help_text
+ _('IMPORTANT: Use this setting only for VERY strict auditing purposes. ' \
+ 'When turned on, nobody will be able to remove the label from any merge requests after they are merged. ' \
+ 'In addition, nobody will be able to turn off this setting or delete this label.')
+ end
+
private
def render_label_link(label_html, link:, title:, dataset:)
- classes = %w(gl-link gl-label-link)
+ classes = %w[gl-link gl-label-link]
dataset ||= {}
if title.present?
diff --git a/app/helpers/markup_helper.rb b/app/helpers/markup_helper.rb
index 1a44f3554b0..1bd5cc41961 100644
--- a/app/helpers/markup_helper.rb
+++ b/app/helpers/markup_helper.rb
@@ -63,7 +63,7 @@ module MarkupHelper
md = markdown_field(object, attribute, options.merge(post_process: false))
return unless md.present?
- tags = %w(a gl-emoji b strong i em pre code p span)
+ tags = %w[a gl-emoji b strong i em pre code p span]
context = markdown_field_render_context(object, attribute, options)
context.reverse_merge!(truncate_visible_max_chars: max_chars || md.length)
@@ -73,11 +73,11 @@ module MarkupHelper
text,
tags: tags,
attributes: Rails::Html::WhiteListSanitizer.allowed_attributes +
- %w(
+ %w[
style data-src data-name data-unicode-version data-html
data-reference-type data-project-path data-iid data-mr-title
data-user
- )
+ ]
)
render_links(text)
diff --git a/app/helpers/members_helper.rb b/app/helpers/members_helper.rb
index 42ffe338367..e4c1d7932aa 100644
--- a/app/helpers/members_helper.rb
+++ b/app/helpers/members_helper.rb
@@ -54,14 +54,6 @@ module MembersHelper
end
end
- def localized_tasks_to_be_done_choices
- {
- code: s_('TasksToBeDone|Create/import code into a project (repository)'),
- ci: s_('TasksToBeDone|Set up CI/CD pipelines to build, test, deploy, and monitor code'),
- issues: s_('TasksToBeDone|Create/import issues (tickets) to collaborate on ideas and plan work')
- }.freeze
- end
-
private
def source_text(member)
diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb
index 32a183d6cd8..a90a16e120c 100644
--- a/app/helpers/merge_requests_helper.rb
+++ b/app/helpers/merge_requests_helper.rb
@@ -226,6 +226,13 @@ module MergeRequestsHelper
}
end
+ def mr_compare_form_data(_, merge_request)
+ {
+ source_branch_url: project_new_merge_request_branch_from_path(merge_request.source_project),
+ target_branch_url: project_new_merge_request_branch_to_path(merge_request.source_project)
+ }
+ end
+
private
def review_requested_merge_requests_count
@@ -269,7 +276,7 @@ module MergeRequestsHelper
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 gl-mr-2', 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')
+ copy_button = clipboard_button(text: merge_request.source_branch, title: _('Copy branch name'), class: '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-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-mx-2'
diff --git a/app/helpers/nav/new_dropdown_helper.rb b/app/helpers/nav/new_dropdown_helper.rb
index 306c4d8694e..5274ace3d8a 100644
--- a/app/helpers/nav/new_dropdown_helper.rb
+++ b/app/helpers/nav/new_dropdown_helper.rb
@@ -157,7 +157,7 @@ module Nav
partial: partial,
component: 'invite_members',
data: {
- trigger_source: 'top-nav',
+ trigger_source: 'top_nav',
trigger_element: 'text-emoji'
}
)
diff --git a/app/helpers/nav_helper.rb b/app/helpers/nav_helper.rb
index 4cbd5029ac9..d3707183964 100644
--- a/app/helpers/nav_helper.rb
+++ b/app/helpers/nav_helper.rb
@@ -79,11 +79,11 @@ module NavHelper
end
def admin_monitoring_nav_links
- %w(system_info background_migrations background_jobs health_check)
+ %w[system_info background_migrations background_jobs health_check]
end
def admin_analytics_nav_links
- %w(dev_ops_report usage_trends)
+ %w[dev_ops_report usage_trends]
end
def show_super_sidebar?(user = current_user)
diff --git a/app/helpers/organizations/organization_helper.rb b/app/helpers/organizations/organization_helper.rb
new file mode 100644
index 00000000000..6b5c4342c5c
--- /dev/null
+++ b/app/helpers/organizations/organization_helper.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+module Organizations
+ module OrganizationHelper
+ def organization_show_app_data(organization)
+ {
+ organization: organization.slice(:id, :name),
+ groups_and_projects_organization_path: groups_and_projects_organization_path(organization),
+ # TODO: Update counts to use real data
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/424531
+ association_counts: {
+ groups: 10,
+ projects: 5,
+ users: 1050
+ }
+ }.merge(shared_groups_and_projects_app_data).to_json
+ end
+
+ def organization_groups_and_projects_app_data
+ shared_groups_and_projects_app_data.to_json
+ end
+
+ private
+
+ def shared_groups_and_projects_app_data
+ {
+ projects_empty_state_svg_path: image_path('illustrations/empty-state/empty-projects-md.svg'),
+ groups_empty_state_svg_path: image_path('illustrations/empty-state/empty-groups-md.svg'),
+ new_group_path: new_group_path,
+ new_project_path: new_project_path
+ }
+ end
+ end
+end
diff --git a/app/helpers/profiles_helper.rb b/app/helpers/profiles_helper.rb
index 05605394d57..8d260d5e455 100644
--- a/app/helpers/profiles_helper.rb
+++ b/app/helpers/profiles_helper.rb
@@ -34,7 +34,7 @@ module ProfilesHelper
def middle_dot_divider_classes(stacking, breakpoint)
['gl-mb-3'].tap do |classes|
if stacking
- classes.concat(%w(middle-dot-divider-sm gl-display-block gl-sm-display-inline-block))
+ classes.concat(%w[middle-dot-divider-sm gl-display-block gl-sm-display-inline-block])
else
classes << 'gl-display-inline-block'
classes << if breakpoint.nil?
diff --git a/app/helpers/projects/observability_helper.rb b/app/helpers/projects/observability_helper.rb
deleted file mode 100644
index 4515fdb1bc3..00000000000
--- a/app/helpers/projects/observability_helper.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-
-module Projects
- module ObservabilityHelper
- def observability_tracing_view_model(project)
- Gitlab::Json.generate({
- tracingUrl: Gitlab::Observability.tracing_url(project),
- provisioningUrl: Gitlab::Observability.provisioning_url(project),
- oauthUrl: Gitlab::Observability.oauth_url
- })
- end
-
- def observability_tracing_details_model(project, trace_id)
- Gitlab::Json.generate({
- tracingIndexUrl: namespace_project_tracing_index_path(project.group, project),
- traceId: trace_id,
- tracingUrl: Gitlab::Observability.tracing_url(project),
- provisioningUrl: Gitlab::Observability.provisioning_url(project),
- oauthUrl: Gitlab::Observability.oauth_url
- })
- end
- end
-end
diff --git a/app/helpers/projects/pipeline_helper.rb b/app/helpers/projects/pipeline_helper.rb
index 42e8e44c94c..0c3b7d26fe2 100644
--- a/app/helpers/projects/pipeline_helper.rb
+++ b/app/helpers/projects/pipeline_helper.rb
@@ -18,7 +18,7 @@ module Projects
suite_endpoint: project_pipeline_test_path(project, pipeline, suite_name: 'suite', format: :json),
blob_path: project_blob_path(project, pipeline.sha),
has_test_report: pipeline.has_test_reports?,
- empty_state_image_path: image_path('illustrations/empty-state/empty-test-cases-lg.svg'),
+ empty_state_image_path: image_path('illustrations/empty-todos-md.svg'),
empty_dag_svg_path: image_path('illustrations/empty-state/empty-dag-md.svg'),
artifacts_expired_image_path: image_path('illustrations/pipeline.svg'),
tests_count: pipeline.test_report_summary.total[:count]
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index 754e1b7c2a2..e45b38f2266 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -373,14 +373,6 @@ module ProjectsHelper
false
end
- def metrics_external_dashboard_url
- @project.metrics_setting_external_dashboard_url
- end
-
- def metrics_dashboard_timezone
- @project.metrics_setting_dashboard_timezone
- end
-
def grafana_integration_url
@project.grafana_integration&.grafana_url
end
diff --git a/app/helpers/registrations_helper.rb b/app/helpers/registrations_helper.rb
index 4acba9b68d7..c2c142bca4d 100644
--- a/app/helpers/registrations_helper.rb
+++ b/app/helpers/registrations_helper.rb
@@ -7,7 +7,7 @@ module RegistrationsHelper
min_length_message: s_('SignUp|Username is too short (minimum is %{min_length} characters).') % { min_length: User::MIN_USERNAME_LENGTH },
max_length: User::MAX_USERNAME_LENGTH,
max_length_message: s_('SignUp|Username is too long (maximum is %{max_length} characters).') % { max_length: User::MAX_USERNAME_LENGTH },
- qa_selector: 'new_user_username_field'
+ testid: 'new-user-username-field'
}
end
diff --git a/app/helpers/routing/projects_helper.rb b/app/helpers/routing/projects_helper.rb
index 9b4aafe49b4..06de9022be4 100644
--- a/app/helpers/routing/projects_helper.rb
+++ b/app/helpers/routing/projects_helper.rb
@@ -43,12 +43,11 @@ module Routing
end
def work_item_url(entity, *args)
- # TODO: we do not have a route to access group level work items yet.
- # That is to be done as part of view group level work item issue:
- # see https://gitlab.com/gitlab-org/gitlab/-/work_items/393987
- return unless entity.project.present?
-
- project_work_items_url(entity.project, entity.iid, *args)
+ if entity.project.present?
+ project_work_items_url(entity.project, entity.iid, *args)
+ else
+ group_work_item_url(entity.namespace, entity.iid, *args)
+ end
end
def merge_request_url(entity, *args)
@@ -94,6 +93,8 @@ module Routing
private
def use_work_items_path?(issue)
+ return true if issue.project.blank? && issue.namespace.present?
+
issue.issue_type == 'task'
end
end
diff --git a/app/helpers/safe_format_helper.rb b/app/helpers/safe_format_helper.rb
index d39a972f3f3..71bfc9ecb40 100644
--- a/app/helpers/safe_format_helper.rb
+++ b/app/helpers/safe_format_helper.rb
@@ -36,7 +36,7 @@ module SafeFormatHelper
# Returns an empty Hash if +tag+ is not a valid paired tag (e.g. <p>foo</p>).
# an empty Hash is returned.
#
- # @param [String] tag is a HTML-safe output from tag helper
+ # @param [String] html_tag is a HTML-safe output from tag helper
# @param [Symbol,Object] open_name name of opening tag
# @param [Symbol,Object] close_name name of closing tag
# @raise [ArgumentError] if +tag+ is not HTML-safe
diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb
index cd32023adb6..f002a0c454d 100644
--- a/app/helpers/search_helper.rb
+++ b/app/helpers/search_helper.rb
@@ -242,7 +242,7 @@ module SearchHelper
elsif current_controller?(:commits)
'commits'
elsif current_controller?(:groups)
- if %w(issues merge_requests).include?(controller.action_name)
+ if %w[issues merge_requests].include?(controller.action_name)
controller.action_name
end
end
@@ -479,7 +479,7 @@ module SearchHelper
end.to_json
end
- def search_filter_input_options(type, placeholder = _('Search or filter results...'))
+ def search_filter_input_options(type, placeholder = _('Search or filter results…'))
opts =
{
id: "filtered-search-#{type}",
@@ -537,14 +537,14 @@ module SearchHelper
source,
count_tags: false,
count_tail: false,
- filtered_tags: %w(img),
+ filtered_tags: %w[img],
max_length: 200
)
end
def search_sanitize(html)
# Truncato's filtered_tags and filtered_attributes are not quite the same
- sanitize(html, tags: %w(a p ol ul li pre code))
+ sanitize(html, tags: %w[a p ol ul li pre code])
end
# _search_highlight is used in EE override
diff --git a/app/helpers/sidebars_helper.rb b/app/helpers/sidebars_helper.rb
index 1bd7da0a352..33ca5ad584e 100644
--- a/app/helpers/sidebars_helper.rb
+++ b/app/helpers/sidebars_helper.rb
@@ -64,7 +64,8 @@ module SidebarsHelper
gitlab_version: Gitlab.version_info,
gitlab_version_check: gitlab_version_check,
search: search_data,
- panel_type: panel_type
+ panel_type: panel_type,
+ shortcut_links: shortcut_links
}
end
@@ -106,7 +107,8 @@ module SidebarsHelper
update_pins_url: pins_path,
is_impersonating: impersonating?,
stop_impersonation_path: admin_impersonation_path,
- shortcut_links: shortcut_links(user, project: project)
+ shortcut_links: shortcut_links(user: user, project: project),
+ track_visits_path: track_namespace_visits_path
})
end
@@ -114,32 +116,43 @@ module SidebarsHelper
nav: nil, project: nil, user: nil, group: nil, current_ref: nil, ref_type: nil,
viewed_user: nil, organization: nil)
context_adds = { route_is_active: method(:active_nav_link?), is_super_sidebar: true }
- case nav
- when 'project'
- context = project_sidebar_context(project, user, current_ref, ref_type: ref_type, **context_adds)
- Sidebars::Projects::SuperSidebarPanel.new(context)
- when 'group'
- context = group_sidebar_context(group, user, **context_adds)
- Sidebars::Groups::SuperSidebarPanel.new(context)
- when 'profile'
- context = Sidebars::Context.new(current_user: user, container: user, **context_adds)
- Sidebars::UserSettings::Panel.new(context)
- when 'user_profile'
- context = Sidebars::Context.new(current_user: user, container: viewed_user, **context_adds)
- Sidebars::UserProfile::Panel.new(context)
- when 'explore'
- Sidebars::Explore::Panel.new(Sidebars::Context.new(current_user: user, container: nil, **context_adds))
- when 'search'
- context = Sidebars::Context.new(current_user: user, container: nil, **context_adds)
- Sidebars::Search::Panel.new(context)
- when 'admin'
- Sidebars::Admin::Panel.new(Sidebars::Context.new(current_user: user, container: nil, **context_adds))
- when 'organization'
- context = organization_sidebar_context(organization, user, **context_adds)
- Sidebars::Organizations::SuperSidebarPanel.new(context)
- else
+ panel = case nav
+ when 'project'
+ context = project_sidebar_context(project, user, current_ref, ref_type: ref_type, **context_adds)
+ Sidebars::Projects::SuperSidebarPanel.new(context)
+ when 'group'
+ context = group_sidebar_context(group, user, **context_adds)
+ Sidebars::Groups::SuperSidebarPanel.new(context)
+ when 'profile'
+ context = Sidebars::Context.new(current_user: user, container: user, **context_adds)
+ Sidebars::UserSettings::Panel.new(context)
+ when 'user_profile'
+ context = Sidebars::Context.new(current_user: user, container: viewed_user, **context_adds)
+ Sidebars::UserProfile::Panel.new(context)
+ when 'explore'
+ Sidebars::Explore::Panel.new(Sidebars::Context.new(current_user: user, container: nil, **context_adds))
+ when 'search'
+ context = Sidebars::Context.new(current_user: user, container: nil, **context_adds)
+ Sidebars::Search::Panel.new(context)
+ when 'admin'
+ Sidebars::Admin::Panel.new(Sidebars::Context.new(current_user: user, container: nil, **context_adds))
+ when 'organization'
+ context = organization_sidebar_context(organization, user, **context_adds)
+ Sidebars::Organizations::SuperSidebarPanel.new(context)
+ when 'your_work'
+ context = your_work_sidebar_context(user, **context_adds)
+ Sidebars::YourWork::Panel.new(context)
+ end
+
+ # We only return the panel if any menu item is rendered, otherwise fallback
+ return panel if panel&.render?
+
+ # Fallback menu "Your work" for logged-in users, "Explore" for logged-out
+ if user
context = your_work_sidebar_context(user, **context_adds)
Sidebars::YourWork::Panel.new(context)
+ else
+ Sidebars::Explore::Panel.new(Sidebars::Context.new(current_user: nil, container: nil, **context_adds))
end
end
@@ -387,7 +400,29 @@ module SidebarsHelper
!!session[:impersonator_id]
end
- def shortcut_links(user, project: nil)
+ def shortcut_links_anonymous
+ [
+ {
+ title: _('Snippets'),
+ href: explore_snippets_path,
+ css_class: 'dashboard-shortcuts-snippets'
+ },
+ {
+ title: _('Groups'),
+ href: explore_groups_path,
+ css_class: 'dashboard-shortcuts-groups'
+ },
+ {
+ title: _('Projects'),
+ href: explore_projects_path,
+ css_class: 'dashboard-shortcuts-projects'
+ }
+ ]
+ end
+
+ def shortcut_links(user: nil, project: nil)
+ return shortcut_links_anonymous unless user
+
shortcut_links = [
{
title: _('Milestones'),
@@ -403,6 +438,16 @@ module SidebarsHelper
title: _('Activity'),
href: activity_dashboard_path,
css_class: 'dashboard-shortcuts-activity'
+ },
+ {
+ title: _('Groups'),
+ href: dashboard_groups_path,
+ css_class: 'dashboard-shortcuts-groups'
+ },
+ {
+ title: _('Projects'),
+ href: dashboard_projects_path,
+ css_class: 'dashboard-shortcuts-projects'
}
]
diff --git a/app/helpers/sidekiq_helper.rb b/app/helpers/sidekiq_helper.rb
index 07d83b8d850..21aa82aff1c 100644
--- a/app/helpers/sidekiq_helper.rb
+++ b/app/helpers/sidekiq_helper.rb
@@ -8,7 +8,7 @@ module SidekiqHelper
(?<state>[DIEKNRSTVWXZLpsl\+<>/\d]+)\s+
(?<start>.+?)\s+
(?<command>(?:ruby\d+:\s+)?sidekiq.*\].*)
- \z}x.freeze
+ \z}x
def parse_sidekiq_ps(line)
match = line.strip.match(SIDEKIQ_PS_REGEXP)
diff --git a/app/helpers/stat_anchors_helper.rb b/app/helpers/stat_anchors_helper.rb
index d9429f28be7..957985d6953 100644
--- a/app/helpers/stat_anchors_helper.rb
+++ b/app/helpers/stat_anchors_helper.rb
@@ -3,7 +3,7 @@
module StatAnchorsHelper
def stat_anchor_attrs(anchor)
{}.tap do |attrs|
- attrs[:class] = %w(nav-link gl-display-flex gl-align-items-center) << extra_classes(anchor)
+ attrs[:class] = %w[nav-link gl-display-flex gl-align-items-center] << extra_classes(anchor)
attrs[:itemprop] = anchor.itemprop if anchor.itemprop
attrs[:data] = anchor.data if anchor.data
end
diff --git a/app/helpers/todos_helper.rb b/app/helpers/todos_helper.rb
index 4f17634f3e4..0d885621b6c 100644
--- a/app/helpers/todos_helper.rb
+++ b/app/helpers/todos_helper.rb
@@ -272,9 +272,9 @@ module TodosHelper
def show_todo_state?(todo)
case todo.target
when MergeRequest, Issue
- %w(closed merged).include?(todo.target.state)
+ %w[closed merged].include?(todo.target.state)
when AlertManagement::Alert
- %i(resolved).include?(todo.target.state)
+ %i[resolved].include?(todo.target.state)
else
false
end
diff --git a/app/helpers/users/callouts_helper.rb b/app/helpers/users/callouts_helper.rb
index 12f78d9bd16..1b5d0b276a3 100644
--- a/app/helpers/users/callouts_helper.rb
+++ b/app/helpers/users/callouts_helper.rb
@@ -14,7 +14,6 @@ module Users
PAGES_MOVED_CALLOUT = 'pages_moved_callout'
REGISTRATION_ENABLED_CALLOUT_ALLOWED_CONTROLLER_PATHS = [/^root/, /^dashboard\S*/, /^admin\S*/].freeze
WEB_HOOK_DISABLED = 'web_hook_disabled'
- ULTIMATE_FEATURE_REMOVAL_BANNER = 'ultimate_feature_removal_banner'
BRANCH_RULES_INFO_CALLOUT = 'branch_rules_info_callout'
NEW_NAVIGATION_CALLOUT = 'new_navigation_callout'
@@ -94,12 +93,6 @@ module Users
Gitlab.com? && current_user.created_at >= Date.new(2023, 6, 2)
end
- def ultimate_feature_removal_banner_dismissed?(project)
- return false unless project
-
- user_dismissed?(ULTIMATE_FEATURE_REMOVAL_BANNER, object: project)
- end
-
private
def user_dismissed?(feature_name, ignore_dismissal_earlier_than = nil, object: nil)
diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb
index ac279904fd2..30f8f6fdfe5 100644
--- a/app/helpers/users_helper.rb
+++ b/app/helpers/users_helper.rb
@@ -164,7 +164,7 @@ module UsersHelper
messageHtml: message,
actionPrimary: {
text: s_('AdminUsers|Confirm user'),
- attributes: [{ variant: 'confirm', 'data-qa-selector': 'confirm_user_confirm_button' }]
+ attributes: [{ variant: 'confirm', 'data-testid': 'confirm-user-confirm-button' }]
},
actionSecondary: {
text: _('Cancel'),
@@ -176,7 +176,7 @@ module UsersHelper
path: confirm_admin_user_path(user),
method: 'put',
modal_attributes: modal_attributes,
- qa_selector: 'confirm_user_button'
+ testid: 'confirm-user-button'
}
end
diff --git a/app/helpers/version_check_helper.rb b/app/helpers/version_check_helper.rb
index dc8ef4e44be..45a4b292eb5 100644
--- a/app/helpers/version_check_helper.rb
+++ b/app/helpers/version_check_helper.rb
@@ -5,9 +5,8 @@ module VersionCheckHelper
def show_version_check?
return false unless Gitlab::CurrentSettings.version_check_enabled
- return false if User.single_user&.requires_usage_stats_consent?
- current_user&.can_read_all_resources?
+ current_user&.can_read_all_resources? && !User.single_user&.requires_usage_stats_consent?
end
def gitlab_version_check
diff --git a/app/helpers/vite_helper.rb b/app/helpers/vite_helper.rb
new file mode 100644
index 00000000000..4d1085a5169
--- /dev/null
+++ b/app/helpers/vite_helper.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+module ViteHelper
+ def universal_javascript_include_tag(*args)
+ if vite_enabled
+ vite_javascript_tag(*args)
+ else
+ javascript_include_tag(*args)
+ end
+ end
+
+ def universal_asset_path(*args)
+ if vite_enabled
+ vite_asset_path(*args)
+ else
+ asset_path(*args)
+ end
+ end
+
+ private
+
+ def vite_enabled
+ Feature.enabled?(:vite) && !Rails.env.test? && vite_running
+ end
+
+ def vite_running
+ ViteRuby.instance.dev_server_running?
+ end
+end
diff --git a/app/helpers/webpack_helper.rb b/app/helpers/webpack_helper.rb
index ba3c232bec4..92874168798 100644
--- a/app/helpers/webpack_helper.rb
+++ b/app/helpers/webpack_helper.rb
@@ -1,6 +1,8 @@
# frozen_string_literal: true
module WebpackHelper
+ include ViteHelper
+
def prefetch_link_tag(source)
href = asset_path(source)
@@ -14,7 +16,11 @@ module WebpackHelper
end
def webpack_bundle_tag(bundle)
- javascript_include_tag(*webpack_entrypoint_paths(bundle))
+ if vite_running
+ vite_javascript_tag bundle
+ else
+ javascript_include_tag(*webpack_entrypoint_paths(bundle))
+ end
end
def webpack_preload_asset_tag(asset, options = {})
@@ -32,6 +38,8 @@ module WebpackHelper
end
def webpack_controller_bundle_tags
+ return if Feature.enabled?(:vite) && !Rails.env.test?
+
chunks = []
action = case controller.action_name
diff --git a/app/helpers/work_items_helper.rb b/app/helpers/work_items_helper.rb
index 9036c7c8347..1969c98de8b 100644
--- a/app/helpers/work_items_helper.rb
+++ b/app/helpers/work_items_helper.rb
@@ -11,4 +11,10 @@ module WorkItemsHelper
report_abuse_path: add_category_abuse_reports_path
}
end
+
+ def work_items_list_data(group)
+ {
+ full_path: group.full_path
+ }
+ end
end