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:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-10-20 12:40:42 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-10-20 12:40:42 +0300
commitee664acb356f8123f4f6b00b73c1e1cf0866c7fb (patch)
treef8479f94a28f66654c6a4f6fb99bad6b4e86a40e /app/helpers
parent62f7d5c5b69180e82ae8196b7b429eeffc8e7b4f (diff)
Add latest changes from gitlab-org/gitlab@15-5-stable-eev15.5.0-rc42
Diffstat (limited to 'app/helpers')
-rw-r--r--app/helpers/application_helper.rb7
-rw-r--r--app/helpers/application_settings_helper.rb3
-rw-r--r--app/helpers/boards_helper.rb25
-rw-r--r--app/helpers/ci/pipeline_editor_helper.rb12
-rw-r--r--app/helpers/ci/pipelines_helper.rb3
-rw-r--r--app/helpers/compare_helper.rb3
-rw-r--r--app/helpers/events_helper.rb48
-rw-r--r--app/helpers/form_helper.rb23
-rw-r--r--app/helpers/groups_helper.rb7
-rw-r--r--app/helpers/hooks_helper.rb7
-rw-r--r--app/helpers/ide_helper.rb32
-rw-r--r--app/helpers/issuables_helper.rb4
-rw-r--r--app/helpers/issues_helper.rb9
-rw-r--r--app/helpers/markup_helper.rb77
-rw-r--r--app/helpers/milestones_helper.rb26
-rw-r--r--app/helpers/nav_helper.rb2
-rw-r--r--app/helpers/projects_helper.rb16
-rw-r--r--app/helpers/recaptcha_helper.rb18
-rw-r--r--app/helpers/releases_helper.rb2
-rw-r--r--app/helpers/search_helper.rb34
-rw-r--r--app/helpers/selects_helper.rb5
-rw-r--r--app/helpers/sessions_helper.rb2
-rw-r--r--app/helpers/time_helper.rb6
-rw-r--r--app/helpers/timeboxes_helper.rb12
-rw-r--r--app/helpers/todos_helper.rb26
-rw-r--r--app/helpers/users/callouts_helper.rb4
-rw-r--r--app/helpers/users_helper.rb15
-rw-r--r--app/helpers/wiki_helper.rb10
28 files changed, 283 insertions, 155 deletions
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index a75c1b16145..32af1599bd1 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -313,7 +313,6 @@ module ApplicationHelper
class_names = []
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 << 'environment-logs-page' if current_controller?(:logs)
class_names << 'with-performance-bar' if performance_bar_enabled?
class_names << system_message_class
class_names << marketing_header_experiment_class
@@ -428,7 +427,7 @@ module ApplicationHelper
milestones: milestones_project_autocomplete_sources_path(object),
commands: commands_project_autocomplete_sources_path(object, type: noteable_type, type_id: params[:id]),
snippets: snippets_project_autocomplete_sources_path(object),
- contacts: contacts_project_autocomplete_sources_path(object)
+ contacts: contacts_project_autocomplete_sources_path(object, type: noteable_type, type_id: params[:id])
}
end
end
@@ -448,6 +447,10 @@ module ApplicationHelper
form_for(record, *(args << options.merge({ builder: ::Gitlab::FormBuilders::GitlabUiFormBuilder })), &block)
end
+ def gitlab_ui_form_with(**args, &block)
+ form_with(**args.merge({ builder: ::Gitlab::FormBuilders::GitlabUiFormBuilder }), &block)
+ end
+
private
def appearance
diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb
index ddc682bc08a..21b18203677 100644
--- a/app/helpers/application_settings_helper.rb
+++ b/app/helpers/application_settings_helper.rb
@@ -441,7 +441,8 @@ module ApplicationSettingsHelper
:group_runner_token_expiration_interval,
:project_runner_token_expiration_interval,
:pipeline_limit_per_project_user_sha,
- :invitation_flow_enforcement
+ :invitation_flow_enforcement,
+ :can_create_group
].tap do |settings|
next if Gitlab.com?
diff --git a/app/helpers/boards_helper.rb b/app/helpers/boards_helper.rb
index f98e70e41d8..db6cf27566f 100644
--- a/app/helpers/boards_helper.rb
+++ b/app/helpers/boards_helper.rb
@@ -2,18 +2,15 @@
module BoardsHelper
def board
- @board ||= @board || @boards.first
+ @board
end
def board_data
{
- boards_endpoint: @boards_endpoint,
- lists_endpoint: board_lists_path(board),
board_id: board.id,
disabled: board.disabled_for?(current_user).to_s,
root_path: root_path,
full_path: full_path,
- bulk_update_path: @bulk_issues_path,
can_update: can_update?.to_s,
can_admin_list: can_admin_list?.to_s,
can_admin_board: can_admin_board?.to_s,
@@ -94,14 +91,6 @@ module BoardsHelper
!multiple_boards_available? && current_board_parent.boards.size > 1
end
- def current_board_path(board)
- @current_board_path ||= if board.group_board?
- group_board_path(current_board_parent, board)
- else
- project_board_path(current_board_parent, board)
- end
- end
-
def current_board_parent
@current_board_parent ||= @group || @project
end
@@ -121,18 +110,6 @@ module BoardsHelper
def can_admin_board?
can?(current_user, :admin_issue_board, current_board_parent)
end
-
- def can_admin_issue?
- can?(current_user, :admin_issue, current_board_parent)
- end
-
- def serializer
- CurrentBoardSerializer.new
- end
-
- def current_board_json
- serializer.represent(board).as_json
- end
end
BoardsHelper.prepend_mod_with('BoardsHelper')
diff --git a/app/helpers/ci/pipeline_editor_helper.rb b/app/helpers/ci/pipeline_editor_helper.rb
index d00301678dd..99a92ba9b59 100644
--- a/app/helpers/ci/pipeline_editor_helper.rb
+++ b/app/helpers/ci/pipeline_editor_helper.rb
@@ -11,7 +11,6 @@ module Ci
def js_pipeline_editor_data(project)
initial_branch = params[:branch_name]
latest_commit = project.repository.commit(initial_branch) || project.commit
- commit_sha = latest_commit ? latest_commit.sha : ''
total_branches = project.repository_exists? ? project.repository.branch_count : 0
{
@@ -27,17 +26,26 @@ module Ci
"lint-unavailable-help-page-path" => help_page_path('ci/pipeline_editor/index', anchor: 'configuration-validation-currently-not-available-message'),
"needs-help-page-path" => help_page_path('ci/yaml/index', anchor: 'needs'),
"new-merge-request-path" => namespace_project_new_merge_request_path,
- "pipeline_etag" => latest_commit ? graphql_etag_pipeline_sha_path(commit_sha) : '',
+ "pipeline_etag" => latest_commit ? graphql_etag_pipeline_sha_path(latest_commit.sha) : '',
"pipeline-page-path" => project_pipelines_path(project),
"project-path" => project.path,
"project-full-path" => project.full_path,
"project-namespace" => project.namespace.full_path,
"simulate-pipeline-help-page-path" => help_page_path('ci/pipeline_editor/index', anchor: 'simulate-a-cicd-pipeline'),
"total-branches" => total_branches,
+ "uses-external-config" => uses_external_config?(project) ? 'true' : 'false',
"validate-tab-illustration-path" => image_path('illustrations/project-run-CICD-pipelines-sm.svg'),
"yml-help-page-path" => help_page_path('ci/yaml/index')
}
end
+
+ private
+
+ def uses_external_config?(project)
+ ci_config_source = Gitlab::Ci::ProjectConfig.new(project: project, sha: nil).source
+
+ [:external_project_source, :remote_source].include?(ci_config_source)
+ end
end
end
diff --git a/app/helpers/ci/pipelines_helper.rb b/app/helpers/ci/pipelines_helper.rb
index a67771116b9..c93c8dd8d76 100644
--- a/app/helpers/ci/pipelines_helper.rb
+++ b/app/helpers/ci/pipelines_helper.rb
@@ -69,7 +69,8 @@ module Ci
end
def has_pipeline_badges?(pipeline)
- pipeline.child? ||
+ pipeline.schedule? ||
+ pipeline.child? ||
pipeline.latest? ||
pipeline.merge_train_pipeline? ||
pipeline.has_yaml_errors? ||
diff --git a/app/helpers/compare_helper.rb b/app/helpers/compare_helper.rb
index e955ad4cfda..9ecf780f55b 100644
--- a/app/helpers/compare_helper.rb
+++ b/app/helpers/compare_helper.rb
@@ -42,7 +42,8 @@ module CompareHelper
source_project_refs_path: refs_project_path(project),
target_project_refs_path: refs_project_path(@target_project),
params_from: params[:from],
- params_to: params[:to]
+ params_to: params[:to],
+ straight: params[:straight]
}.tap do |data|
data[:projects_from] = target_projects(project).map do |target_project|
{ id: target_project.id, name: target_project.full_path }
diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb
index bcddb889cf4..b717cbcc312 100644
--- a/app/helpers/events_helper.rb
+++ b/app/helpers/events_helper.rb
@@ -16,6 +16,54 @@ module EventsHelper
'joined' => 'users'
}.freeze
+ def localized_action_name_map
+ {
+ accepted: s_('Event|accepted'),
+ approved: s_('Event|approved'),
+ closed: s_('Event|closed'),
+ 'commented on': s_('Event|commented on'),
+ created: s_('Event|created'),
+ destroyed: s_('Event|destroyed'),
+ joined: s_('Event|joined'),
+ left: s_('Event|left'),
+ opened: s_('Event|opened'),
+ updated: s_('Event|updated'),
+ 'removed due to membership expiration from': s_('Event|removed due to membership expiration from')
+ }.merge(localized_push_action_name_map,
+ localized_created_project_action_name_map,
+ localized_design_action_names
+ ).freeze
+ end
+
+ def localized_push_action_name_map
+ {
+ 'pushed new': s_('Event|pushed new'),
+ deleted: s_('Event|deleted'),
+ 'pushed to': s_('Event|pushed to')
+ }.freeze
+ end
+
+ def localized_created_project_action_name_map
+ {
+ created: s_('Event|created'),
+ imported: s_('Event|imported')
+ }.freeze
+ end
+
+ def localized_design_action_names
+ {
+ added: s_('Event|added'),
+ updated: s_('Event|updated'),
+ removed: s_('Event|removed')
+ }.freeze
+ end
+
+ def localized_action_name(event)
+ action_name = event.action_name
+ # The action fallback is used to cover the types were not included in the maps.
+ localized_action_name_map[action_name.to_sym] || action_name
+ end
+
def link_to_author(event, self_added: false)
author = event.author
diff --git a/app/helpers/form_helper.rb b/app/helpers/form_helper.rb
index f2e24f54391..9e42aeea9ce 100644
--- a/app/helpers/form_helper.rb
+++ b/app/helpers/form_helper.rb
@@ -39,13 +39,13 @@ module FormHelper
end
end
- def dropdown_max_select(data)
- return data[:'max-select'] unless Feature.enabled?(:limit_reviewer_and_assignee_size)
+ def dropdown_max_select(data, feature_flag)
+ return data[:'max-select'] unless Feature.enabled?(feature_flag)
- if data[:'max-select'] && data[:'max-select'] < MergeRequest::MAX_NUMBER_OF_ASSIGNEES_OR_REVIEWERS
+ if data[:'max-select'] && data[:'max-select'] < ::Issuable::MAX_NUMBER_OF_ASSIGNEES_OR_REVIEWERS
data[:'max-select']
else
- MergeRequest::MAX_NUMBER_OF_ASSIGNEES_OR_REVIEWERS
+ ::Issuable::MAX_NUMBER_OF_ASSIGNEES_OR_REVIEWERS
end
end
@@ -117,10 +117,16 @@ module FormHelper
dropdown_data = multiple_reviewers_dropdown_options(dropdown_data)
end
+ dropdown_data[:data].merge!(reviewers_dropdown_options_for_suggested_reviewers)
dropdown_data
end
# Overwritten
+ def reviewers_dropdown_options_for_suggested_reviewers
+ {}
+ end
+
+ # Overwritten
def issue_supports_multiple_assignees?
false
end
@@ -156,7 +162,12 @@ module FormHelper
new_options[:title] = _('Select assignee(s)')
new_options[:data][:'dropdown-header'] = 'Assignee(s)'
- new_options[:data].delete(:'max-select')
+
+ if Feature.enabled?(:limit_assignees_per_issuable)
+ new_options[:data][:'max-select'] = ::Issuable::MAX_NUMBER_OF_ASSIGNEES_OR_REVIEWERS
+ else
+ new_options[:data].delete(:'max-select')
+ end
new_options
end
@@ -168,7 +179,7 @@ module FormHelper
new_options[:data][:'dropdown-header'] = _('Reviewer(s)')
if Feature.enabled?(:limit_reviewer_and_assignee_size)
- new_options[:data][:'max-select'] = MergeRequest::MAX_NUMBER_OF_ASSIGNEES_OR_REVIEWERS
+ new_options[:data][:'max-select'] = ::Issuable::MAX_NUMBER_OF_ASSIGNEES_OR_REVIEWERS
else
new_options[:data].delete(:'max-select')
end
diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb
index f77bd6621f9..6b00c213875 100644
--- a/app/helpers/groups_helper.rb
+++ b/app/helpers/groups_helper.rb
@@ -126,8 +126,8 @@ module GroupsHelper
group.root? && current_user.can?(:admin_setting_to_allow_project_access_token_creation, group)
end
- def show_thanks_for_purchase_alert?
- params.key?(:purchased_quantity) && params[:purchased_quantity].to_i > 0
+ def show_thanks_for_purchase_alert?(quantity)
+ quantity.to_i > 0
end
def project_list_sort_by
@@ -177,7 +177,8 @@ module GroupsHelper
subgroups_and_projects_endpoint: group_children_path(group, format: :json),
shared_projects_endpoint: group_shared_projects_path(group, format: :json),
archived_projects_endpoint: group_children_path(group, format: :json, archived: 'only'),
- current_group_visibility: group.visibility
+ current_group_visibility: group.visibility,
+ initial_sort: project_list_sort_by
}.merge(subgroups_and_projects_list_app_data(group))
end
diff --git a/app/helpers/hooks_helper.rb b/app/helpers/hooks_helper.rb
index 1e50033e0e0..e050ccc0e40 100644
--- a/app/helpers/hooks_helper.rb
+++ b/app/helpers/hooks_helper.rb
@@ -1,6 +1,13 @@
# frozen_string_literal: true
module HooksHelper
+ def webhook_form_data(hook)
+ {
+ url: hook.url,
+ url_variables: nil
+ }
+ end
+
def link_to_test_hook(hook, trigger)
path = test_hook_path(hook, trigger)
trigger_human_name = trigger.to_s.tr('_', ' ').camelize
diff --git a/app/helpers/ide_helper.rb b/app/helpers/ide_helper.rb
index ec1327cf7ae..5b3ca25b5af 100644
--- a/app/helpers/ide_helper.rb
+++ b/app/helpers/ide_helper.rb
@@ -3,6 +3,32 @@
module IdeHelper
def ide_data
{
+ 'can-use-new-web-ide' => can_use_new_web_ide?.to_s,
+ 'use-new-web-ide' => use_new_web_ide?.to_s,
+ 'user-preferences-path' => profile_preferences_path,
+ 'branch-name' => @branch
+ }.merge(use_new_web_ide? ? new_ide_data : legacy_ide_data)
+ end
+
+ def can_use_new_web_ide?
+ Feature.enabled?(:vscode_web_ide, current_user)
+ end
+
+ def use_new_web_ide?
+ can_use_new_web_ide? && !current_user.use_legacy_web_ide
+ end
+
+ private
+
+ def new_ide_data
+ {
+ 'project-path' => @project&.path_with_namespace,
+ 'csp-nonce' => content_security_policy_nonce
+ }
+ end
+
+ def legacy_ide_data
+ {
'empty-state-svg-path' => image_path('illustrations/multi_file_editor_empty.svg'),
'no-changes-state-svg-path' => image_path('illustrations/multi-editor_no_changes_empty.svg'),
'committed-state-svg-path' => image_path('illustrations/multi-editor_all_changes_committed_empty.svg'),
@@ -13,7 +39,6 @@ module IdeHelper
'clientside-preview-enabled': Gitlab::CurrentSettings.web_ide_clientside_preview_enabled?.to_s,
'render-whitespace-in-code': current_user.render_whitespace_in_code.to_s,
'codesandbox-bundler-url': Gitlab::CurrentSettings.web_ide_clientside_preview_bundler_url,
- 'branch-name' => @branch,
'default-branch' => @project && @project.default_branch,
'file-path' => @path,
'merge-request' => @merge_request,
@@ -24,13 +49,10 @@ module IdeHelper
'web-terminal-svg-path' => image_path('illustrations/web-ide_promotion.svg'),
'web-terminal-help-path' => help_page_path('user/project/web_ide/index.md', anchor: 'interactive-web-terminals-for-the-web-ide'),
'web-terminal-config-help-path' => help_page_path('user/project/web_ide/index.md', anchor: 'web-ide-configuration-file'),
- 'web-terminal-runners-help-path' => help_page_path('user/project/web_ide/index.md', anchor: 'runner-configuration'),
- 'csp-nonce' => content_security_policy_nonce
+ 'web-terminal-runners-help-path' => help_page_path('user/project/web_ide/index.md', anchor: 'runner-configuration')
}
end
- private
-
def convert_to_project_entity_json(project)
return unless project
diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb
index 96daf398243..2804a58da9e 100644
--- a/app/helpers/issuables_helper.rb
+++ b/app/helpers/issuables_helper.rb
@@ -157,9 +157,9 @@ module IssuablesHelper
if issuable.respond_to?(:work_item_type) && WorkItems::Type::WI_TYPES_WITH_CREATED_HEADER.include?(issuable.work_item_type.base_type)
output << content_tag(:span, sprite_icon("#{issuable.work_item_type.icon_name}", css_class: 'gl-icon gl-vertical-align-middle gl-text-gray-500'), class: 'gl-mr-2', aria: { hidden: 'true' })
- output << s_('IssuableStatus|%{wi_type} created %{created_at} by ').html_safe % { wi_type: issuable.issue_type.capitalize, created_at: time_ago_with_tooltip(issuable.created_at) }
+ output << content_tag(:span, s_('IssuableStatus|%{wi_type} created %{created_at} by ').html_safe % { wi_type: issuable.issue_type.capitalize, created_at: time_ago_with_tooltip(issuable.created_at) }, class: 'gl-mr-2' )
else
- output << s_('IssuableStatus|Created %{created_at} by').html_safe % { created_at: time_ago_with_tooltip(issuable.created_at) }
+ 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
diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb
index a157b1b7b21..115cdd432e3 100644
--- a/app/helpers/issues_helper.rb
+++ b/app/helpers/issues_helper.rb
@@ -3,6 +3,10 @@
module IssuesHelper
include Issues::IssueTypeHelpers
+ def can_admin_issue?
+ can?(current_user, :admin_issue, @group || @project)
+ end
+
def issue_css_classes(issue)
classes = ["issue"]
classes << "closed" if issue.closed?
@@ -11,6 +15,11 @@ module IssuesHelper
classes.join(' ')
end
+ def show_timeline_view_toggle?(issue)
+ # Overridden in EE
+ false
+ end
+
def issue_manual_ordering_class
is_sorting_by_relative_position = @sort == 'relative_position'
diff --git a/app/helpers/markup_helper.rb b/app/helpers/markup_helper.rb
index fc558958ca3..866399f3021 100644
--- a/app/helpers/markup_helper.rb
+++ b/app/helpers/markup_helper.rb
@@ -12,22 +12,6 @@ module MarkupHelper
# https://gitlab.com/gitlab-org/gitlab/-/issues/365358
RENDER_TIMEOUT = 5.seconds
- def plain?(filename)
- Gitlab::MarkupHelper.plain?(filename)
- end
-
- def markup?(filename)
- Gitlab::MarkupHelper.markup?(filename)
- end
-
- def gitlab_markdown?(filename)
- Gitlab::MarkupHelper.gitlab_markdown?(filename)
- end
-
- def asciidoc?(filename)
- Gitlab::MarkupHelper.asciidoc?(filename)
- end
-
# Use this in places where you would normally use link_to(gfm(...), ...).
def link_to_markdown(body, url, html_options = {})
return '' if body.blank?
@@ -88,8 +72,10 @@ module MarkupHelper
tags = %w(a gl-emoji b strong i em pre code p span)
tags << 'img' if options[:allow_images]
- text = truncate_visible(md, max_chars || md.length)
- text = prepare_for_rendering(text, markdown_field_render_context(object, attribute, options))
+ context = markdown_field_render_context(object, attribute, options)
+ context.reverse_merge!(truncate_visible_max_chars: max_chars || md.length)
+
+ text = prepare_for_rendering(md, context)
text = sanitize(
text,
tags: tags,
@@ -146,11 +132,11 @@ module MarkupHelper
return '' unless text.present?
markup = proc do
- if gitlab_markdown?(file_name)
+ if Gitlab::MarkupHelper.gitlab_markdown?(file_name)
markdown_unsafe(text, context)
- elsif asciidoc?(file_name)
+ elsif Gitlab::MarkupHelper.asciidoc?(file_name)
asciidoc_unsafe(text, context)
- elsif plain?(file_name)
+ elsif Gitlab::MarkupHelper.plain?(file_name)
plain_unsafe(text)
else
other_markup_unsafe(file_name, text, context)
@@ -207,55 +193,6 @@ module MarkupHelper
{ project: wiki.container }
end
- # Return +text+, truncated to +max_chars+ characters, excluding any HTML
- # tags.
- def truncate_visible(text, max_chars)
- doc = Nokogiri::HTML.fragment(text)
- content_length = 0
- truncated = false
-
- doc.traverse do |node|
- if node.text? || node.content.empty?
- if truncated
- node.remove
- next
- end
-
- # Handle line breaks within a node
- if node.content.strip.lines.length > 1
- node.content = "#{node.content.lines.first.chomp}..."
- truncated = true
- end
-
- num_remaining = max_chars - content_length
- if node.content.length > num_remaining
- node.content = node.content.truncate(num_remaining)
- truncated = true
- end
-
- content_length += node.content.length
- end
-
- truncated = truncate_if_block(node, truncated)
- end
-
- doc.to_html
- end
-
- # Used by #truncate_visible. If +node+ is the first block element, and the
- # text hasn't already been truncated, then append "..." to the node contents
- # and return true. Otherwise return false.
- def truncate_if_block(node, truncated)
- return true if truncated
-
- if node.element? && (node.description&.block? || node.matches?('pre > code > .line'))
- node.inner_html = "#{node.inner_html}..." if node.next_sibling
- true
- else
- truncated
- end
- end
-
def strip_empty_link_tags(text)
scrubber = Loofah::Scrubber.new do |node|
node.remove if node.name == 'a' && node.children.empty?
diff --git a/app/helpers/milestones_helper.rb b/app/helpers/milestones_helper.rb
new file mode 100644
index 00000000000..272a3970bc2
--- /dev/null
+++ b/app/helpers/milestones_helper.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+module MilestonesHelper
+ def milestone_header_class(primary, issuables)
+ header_color = milestone_header_color(primary: primary)
+ header_border = milestone_header_border(issuables)
+
+ "#{header_color} #{header_border} gl-display-flex"
+ end
+
+ def milestone_counter_class(primary)
+ primary ? 'gl-text-white' : 'gl-text-gray-500'
+ end
+
+ private
+
+ def milestone_header_color(primary: false)
+ return '' unless primary
+
+ 'gl-bg-blue-500 gl-text-white'
+ end
+
+ def milestone_header_border(issuables)
+ issuables.empty? ? 'gl-border-bottom-0 gl-rounded-base' : ''
+ end
+end
diff --git a/app/helpers/nav_helper.rb b/app/helpers/nav_helper.rb
index 4d6ab7b8bf9..0cf2c5cea4c 100644
--- a/app/helpers/nav_helper.rb
+++ b/app/helpers/nav_helper.rb
@@ -49,7 +49,7 @@ module NavHelper
end
def page_has_markdown?
- current_path?('merge_requests#show') ||
+ current_path?('projects/merge_requests#show') ||
current_path?('projects/merge_requests/conflicts#show') ||
current_path?('issues#show') ||
current_path?('milestones#show') ||
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index e760fad7be9..cddcdf77710 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -471,8 +471,24 @@ module ProjectsHelper
}
end
+ def localized_project_human_access(access)
+ localized_access_names[access] || Gitlab::Access.human_access(access)
+ end
+
private
+ def localized_access_names
+ {
+ Gitlab::Access::NO_ACCESS => _('No access'),
+ Gitlab::Access::MINIMAL_ACCESS => _("Minimal Access"),
+ Gitlab::Access::GUEST => _('Guest'),
+ Gitlab::Access::REPORTER => _('Reporter'),
+ Gitlab::Access::DEVELOPER => _('Developer'),
+ Gitlab::Access::MAINTAINER => _('Maintainer'),
+ Gitlab::Access::OWNER => _('Owner')
+ }
+ end
+
def configure_oauth_import_message(provider, help_url)
str = if current_user.admin?
'ImportProjects|To enable importing projects from %{provider}, as administrator you need to configure %{link_start}OAuth integration%{link_end}'
diff --git a/app/helpers/recaptcha_helper.rb b/app/helpers/recaptcha_helper.rb
index 5b17ab4b815..59f0dc8f819 100644
--- a/app/helpers/recaptcha_helper.rb
+++ b/app/helpers/recaptcha_helper.rb
@@ -2,9 +2,27 @@
module RecaptchaHelper
def recaptcha_enabled?
+ return false if gitlab_qa?
+
!!Gitlab::Recaptcha.enabled?
end
alias_method :show_recaptcha_sign_up?, :recaptcha_enabled?
+
+ def recaptcha_enabled_on_login?
+ return false if gitlab_qa?
+
+ Gitlab::Recaptcha.enabled_on_login?
+ end
+
+ private
+
+ def gitlab_qa?
+ return false unless Gitlab.com?
+ return false unless request.user_agent.present?
+ return false unless Gitlab::Environment.qa_user_agent.present?
+
+ ActiveSupport::SecurityUtils.secure_compare(request.user_agent, Gitlab::Environment.qa_user_agent)
+ end
end
RecaptchaHelper.prepend_mod
diff --git a/app/helpers/releases_helper.rb b/app/helpers/releases_helper.rb
index 50089c7edab..e0db40ebaee 100644
--- a/app/helpers/releases_helper.rb
+++ b/app/helpers/releases_helper.rb
@@ -82,7 +82,7 @@ module ReleasesHelper
markdown_docs_path: help_page_path('user/markdown'),
release_assets_docs_path: releases_help_page_path(anchor: 'release-assets'),
manage_milestones_path: project_milestones_path(@project),
- new_milestone_path: new_project_milestone_path(@project),
+ new_milestone_path: new_project_milestone_path(@project, redirect_path: 'new_release'),
edit_release_docs_path: releases_help_page_path(anchor: 'edit-a-release'),
upcoming_release_docs_path: releases_help_page_path(anchor: 'upcoming-releases')
}
diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb
index b16235893ae..f2b88287277 100644
--- a/app/helpers/search_helper.rb
+++ b/app/helpers/search_helper.rb
@@ -380,6 +380,40 @@ module SearchHelper
end
end
+ def search_filter_link_json(scope, label, data, search)
+ scope_name = scope.to_s
+ search_params = params.merge(search).merge({ scope: scope_name }).permit(SEARCH_GENERIC_PARAMS)
+ active_scope = @scope == scope_name
+
+ result = { label: label, scope: scope_name, data: data, link: search_path(search_params), active: active_scope }
+ result[:count] = @search_results.formatted_count(scope_name) if active_scope && !@timeout
+ result[:count_link] = search_count_path(search_params) unless active_scope
+
+ result
+ end
+
+ # search page scope navigation
+ def search_navigation
+ {
+ projects: { label: _("Projects"), data: { qa_selector: 'projects_tab' }, condition: @project.nil? },
+ blobs: { label: _("Code"), data: { qa_selector: 'code_tab' }, condition: project_search_tabs?(:blobs) || search_service.show_elasticsearch_tabs? || feature_flag_tab_enabled?(:global_search_code_tab) },
+ issues: { label: _("Issues"), condition: project_search_tabs?(:issues) || feature_flag_tab_enabled?(:global_search_issues_tab) },
+ merge_requests: { label: _("Merge requests"), condition: project_search_tabs?(:merge_requests) || feature_flag_tab_enabled?(:global_search_merge_requests_tab) },
+ wiki_blobs: { label: _("Wiki"), condition: project_search_tabs?(:wiki) || search_service.show_elasticsearch_tabs? },
+ commits: { label: _("Commits"), condition: project_search_tabs?(:commits) || (search_service.show_elasticsearch_tabs? && feature_flag_tab_enabled?(:global_search_commits_tab)) },
+ notes: { label: _("Comments"), condition: project_search_tabs?(:notes) || search_service.show_elasticsearch_tabs? },
+ milestones: { label: _("Milestones"), condition: project_search_tabs?(:milestones) || @project.nil? },
+ users: { label: _("Users"), condition: show_user_search_tab? },
+ snippet_titles: { label: _("Titles and Descriptions"), search: { snippets: true, group_id: nil, project_id: nil }, condition: @show_snippets.present? && @project.nil? }
+ }
+ end
+
+ def search_navigation_json
+ search_navigation.each_with_object({}) do |(key, value), hash|
+ hash[key] = search_filter_link_json(key, value[:label], value[:data], value[:search]) if value[:condition]
+ end.to_json
+ end
+
def search_filter_input_options(type, placeholder = _('Search or filter results...'))
opts =
{
diff --git a/app/helpers/selects_helper.rb b/app/helpers/selects_helper.rb
index 88aff31af54..14ee6007a43 100644
--- a/app/helpers/selects_helper.rb
+++ b/app/helpers/selects_helper.rb
@@ -39,11 +39,6 @@ module SelectsHelper
select2_tag(id, opts)
end
- def namespace_select_tag(id, opts = {})
- opts[:class] = [*opts[:class], 'ajax-namespace-select'].join(' ')
- select2_tag(id, opts)
- end
-
def project_select_tag(id, opts = {})
opts[:class] = [*opts[:class], 'ajax-project-select'].join(' ')
diff --git a/app/helpers/sessions_helper.rb b/app/helpers/sessions_helper.rb
index 129180d1ccf..56138ba95c2 100644
--- a/app/helpers/sessions_helper.rb
+++ b/app/helpers/sessions_helper.rb
@@ -49,6 +49,6 @@ module SessionsHelper
match = regex.match(email)
return email unless match
- match[1] + '*' * match[2].length + match[3] + '*' * match[4].length + match[5]
+ match[1] + '*' * (match[2] || '').length + match[3] + '*' * (match[4] || '').length + match[5]
end
end
diff --git a/app/helpers/time_helper.rb b/app/helpers/time_helper.rb
index ecedbfb2a4f..cb6f60ab79b 100644
--- a/app/helpers/time_helper.rb
+++ b/app/helpers/time_helper.rb
@@ -8,12 +8,12 @@ module TimeHelper
if minutes >= 1
if seconds % 60 == 0
- pluralize(minutes, "minute")
+ n_('%d minute', '%d minutes', minutes) % minutes
else
- [pluralize(minutes, "minute"), pluralize(seconds, "second")].to_sentence
+ [n_('%d minute', '%d minutes', minutes) % minutes, n_('%d second', '%d seconds', seconds) % seconds].to_sentence
end
else
- pluralize(seconds, "second")
+ n_('%d second', '%d seconds', seconds) % seconds
end
end
diff --git a/app/helpers/timeboxes_helper.rb b/app/helpers/timeboxes_helper.rb
index 11d09a79dcf..e0e6229bc6d 100644
--- a/app/helpers/timeboxes_helper.rb
+++ b/app/helpers/timeboxes_helper.rb
@@ -77,14 +77,10 @@ module TimeboxesHelper
end
def milestone_progress_bar(milestone)
- options = {
- class: 'progress-bar bg-success',
- style: "width: #{milestone.percent_complete}%;"
- }
-
- content_tag :div, class: 'progress' do
- content_tag :div, nil, options
- end
+ render Pajamas::ProgressComponent.new(
+ value: milestone.percent_complete,
+ variant: :success
+ )
end
def milestone_time_for(date, date_type)
diff --git a/app/helpers/todos_helper.rb b/app/helpers/todos_helper.rb
index ecf29c41100..520cde9ecee 100644
--- a/app/helpers/todos_helper.rb
+++ b/app/helpers/todos_helper.rb
@@ -130,12 +130,12 @@ module TodosHelper
def todos_filter_params
{
- state: params[:state],
+ state: params[:state].presence,
project_id: params[:project_id],
author_id: params[:author_id],
type: params[:type],
action_id: params[:action_id]
- }
+ }.compact
end
def todos_filter_empty?
@@ -168,22 +168,22 @@ module TodosHelper
def todo_actions_options
[
- { id: '', text: 'Any Action' },
- { id: Todo::ASSIGNED, text: 'Assigned' },
- { id: Todo::REVIEW_REQUESTED, text: 'Review requested' },
- { id: Todo::MENTIONED, text: 'Mentioned' },
- { id: Todo::MARKED, text: 'Added' },
- { id: Todo::BUILD_FAILED, text: 'Pipelines' }
+ { id: '', text: s_('Todos|Any Action') },
+ { id: Todo::ASSIGNED, text: s_('Todos|Assigned') },
+ { id: Todo::REVIEW_REQUESTED, text: s_('Todos|Review requested') },
+ { id: Todo::MENTIONED, text: s_('Todos|Mentioned') },
+ { id: Todo::MARKED, text: s_('Todos|Added') },
+ { id: Todo::BUILD_FAILED, text: s_('Todos|Pipelines') }
]
end
def todo_types_options
[
- { id: '', text: 'Any Type' },
- { id: 'Issue', text: 'Issue' },
- { id: 'MergeRequest', text: 'Merge request' },
- { id: 'DesignManagement::Design', text: 'Design' },
- { id: 'AlertManagement::Alert', text: 'Alert' }
+ { id: '', text: s_('Todos|Any Type') },
+ { id: 'Issue', text: s_('Todos|Issue') },
+ { id: 'MergeRequest', text: s_('Todos|Merge request') },
+ { id: 'DesignManagement::Design', text: s_('Todos|Design') },
+ { id: 'AlertManagement::Alert', text: s_('Todos|Alert') }
]
end
diff --git a/app/helpers/users/callouts_helper.rb b/app/helpers/users/callouts_helper.rb
index d8baa185370..a9fd219bbac 100644
--- a/app/helpers/users/callouts_helper.rb
+++ b/app/helpers/users/callouts_helper.rb
@@ -76,8 +76,8 @@ module Users
user_dismissed?(WEB_HOOK_DISABLED, last_failure, project: project)
end
- def show_merge_request_settings_callout?
- !user_dismissed?(MERGE_REQUEST_SETTINGS_MOVED_CALLOUT)
+ def show_merge_request_settings_callout?(project)
+ !user_dismissed?(MERGE_REQUEST_SETTINGS_MOVED_CALLOUT) && project.merge_requests_enabled?
end
def ultimate_feature_removal_banner_dismissed?(project)
diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb
index 271fa47dd97..4f345fdeb9c 100644
--- a/app/helpers/users_helper.rb
+++ b/app/helpers/users_helper.rb
@@ -287,6 +287,21 @@ module UsersHelper
}
]
end
+
+ # the keys should match the user model defined roles in app/models/user.rb
+ def localized_user_roles
+ {
+ software_developer: s_('User|Software Developer'),
+ development_team_lead: s_('User|Development Team Lead'),
+ devops_engineer: s_('User|Devops Engineer'),
+ systems_administrator: s_('User|Systems Administrator'),
+ security_analyst: s_('User|Security Analyst'),
+ data_analyst: s_('User|Data Analyst'),
+ product_manager: s_('User|Product Manager'),
+ product_designer: s_('User|Product Designer'),
+ other: s_('User|Other')
+ }.with_indifferent_access.freeze
+ end
end
UsersHelper.prepend_mod_with('UsersHelper')
diff --git a/app/helpers/wiki_helper.rb b/app/helpers/wiki_helper.rb
index d6ffd3deafe..017a1861905 100644
--- a/app/helpers/wiki_helper.rb
+++ b/app/helpers/wiki_helper.rb
@@ -59,14 +59,16 @@ module WikiHelper
end
end
- def wiki_sort_controls(wiki, sort, direction)
- sort ||= Wiki::TITLE_ORDER
+ def wiki_sort_controls(wiki, direction)
link_class = 'gl-button btn btn-default btn-icon has-tooltip reverse-sort-btn qa-reverse-sort rspec-reverse-sort'
reversed_direction = direction == 'desc' ? 'asc' : 'desc'
icon_class = direction == 'desc' ? 'highest' : 'lowest'
+ title = direction == 'desc' ? _('Sort direction: Descending') : _('Sort direction: Ascending')
- link_to(wiki_path(wiki, action: :pages, sort: sort, direction: reversed_direction),
- type: 'button', class: link_class, title: _('Sort direction')) do
+ link_options = { action: :pages, direction: reversed_direction }
+
+ link_to(wiki_path(wiki, **link_options),
+ type: 'button', class: link_class, title: title) do
sprite_icon("sort-#{icon_class}")
end
end