summaryrefslogtreecommitdiff
path: root/app/helpers
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-10-21 07:08:36 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-10-21 07:08:36 +0000
commit48aff82709769b098321c738f3444b9bdaa694c6 (patch)
treee00c7c43e2d9b603a5a6af576b1685e400410dee /app/helpers
parent879f5329ee916a948223f8f43d77fba4da6cd028 (diff)
downloadgitlab-ce-48aff82709769b098321c738f3444b9bdaa694c6.tar.gz
Add latest changes from gitlab-org/gitlab@13-5-stable-eev13.5.0-rc42
Diffstat (limited to 'app/helpers')
-rw-r--r--app/helpers/analytics/navbar_helper.rb2
-rw-r--r--app/helpers/analytics/unique_visits_helper.rb3
-rw-r--r--app/helpers/application_helper.rb24
-rw-r--r--app/helpers/application_settings_helper.rb14
-rw-r--r--app/helpers/avatars_helper.rb2
-rw-r--r--app/helpers/blob_helper.rb26
-rw-r--r--app/helpers/boards_helper.rb22
-rw-r--r--app/helpers/ci/runners_helper.rb8
-rw-r--r--app/helpers/clusters_helper.rb20
-rw-r--r--app/helpers/container_expiration_policies_helper.rb5
-rw-r--r--app/helpers/dropdowns_helper.rb2
-rw-r--r--app/helpers/emails_helper.rb20
-rw-r--r--app/helpers/events_helper.rb16
-rw-r--r--app/helpers/external_link_helper.rb2
-rw-r--r--app/helpers/feature_flags_helper.rb19
-rw-r--r--app/helpers/form_helper.rb26
-rw-r--r--app/helpers/gitlab_routing_helper.rb12
-rw-r--r--app/helpers/gitpod_helper.rb10
-rw-r--r--app/helpers/groups/group_members_helper.rb42
-rw-r--r--app/helpers/icons_helper.rb20
-rw-r--r--app/helpers/invite_members_helper.rb21
-rw-r--r--app/helpers/issuables_helper.rb58
-rw-r--r--app/helpers/issues_helper.rb15
-rw-r--r--app/helpers/labels_helper.rb31
-rw-r--r--app/helpers/merge_requests_helper.rb4
-rw-r--r--app/helpers/mirror_helper.rb6
-rw-r--r--app/helpers/namespaces_helper.rb2
-rw-r--r--app/helpers/nav_helper.rb3
-rw-r--r--app/helpers/operations_helper.rb2
-rw-r--r--app/helpers/packages_helper.rb22
-rw-r--r--app/helpers/page_layout_helper.rb8
-rw-r--r--app/helpers/pagination_helper.rb10
-rw-r--r--app/helpers/preferences_helper.rb4
-rw-r--r--app/helpers/projects/alert_management_helper.rb4
-rw-r--r--app/helpers/projects/incidents_helper.rb7
-rw-r--r--app/helpers/projects_helper.rb32
-rw-r--r--app/helpers/releases_helper.rb9
-rw-r--r--app/helpers/reminder_emails_helper.rb76
-rw-r--r--app/helpers/search_helper.rb51
-rw-r--r--app/helpers/services_helper.rb6
-rw-r--r--app/helpers/snippets_helper.rb25
-rw-r--r--app/helpers/ssh_keys_helper.rb18
-rw-r--r--app/helpers/startupjs_helper.rb17
-rw-r--r--app/helpers/suggest_pipeline_helper.rb2
-rw-r--r--app/helpers/system_note_helper.rb6
-rw-r--r--app/helpers/tags_helper.rb9
-rw-r--r--app/helpers/timeboxes_helper.rb4
-rw-r--r--app/helpers/todos_helper.rb9
-rw-r--r--app/helpers/tree_helper.rb45
-rw-r--r--app/helpers/user_callouts_helper.rb6
-rw-r--r--app/helpers/users_helper.rb13
-rw-r--r--app/helpers/visibility_level_helper.rb17
-rw-r--r--app/helpers/web_ide_button_helper.rb61
-rw-r--r--app/helpers/webpack_helper.rb14
-rw-r--r--app/helpers/whats_new_helper.rb27
-rw-r--r--app/helpers/wiki_helper.rb3
56 files changed, 681 insertions, 261 deletions
diff --git a/app/helpers/analytics/navbar_helper.rb b/app/helpers/analytics/navbar_helper.rb
index ddf2655c887..bc0b5e7c74f 100644
--- a/app/helpers/analytics/navbar_helper.rb
+++ b/app/helpers/analytics/navbar_helper.rb
@@ -28,7 +28,7 @@ module Analytics
private
def navbar_sub_item(args)
- NavbarSubItem.new(args)
+ NavbarSubItem.new(**args)
end
def cycle_analytics_navbar_link(project, current_user)
diff --git a/app/helpers/analytics/unique_visits_helper.rb b/app/helpers/analytics/unique_visits_helper.rb
index ded7f54e44e..4c709b2ed23 100644
--- a/app/helpers/analytics/unique_visits_helper.rb
+++ b/app/helpers/analytics/unique_visits_helper.rb
@@ -14,8 +14,7 @@ module Analytics
end
def track_visit(target_id)
- return unless Feature.enabled?(:track_unique_visits)
- return unless Gitlab::CurrentSettings.usage_ping_enabled?
+ return unless Feature.enabled?(:track_unique_visits, default_enabled: true)
return unless visitor_id
Gitlab::Analytics::UniqueVisits.new.track_visit(visitor_id, target_id)
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index a81225c8954..2a6b00c0bd8 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -6,10 +6,18 @@ require 'uri'
module ApplicationHelper
include StartupCssHelper
- # See https://docs.gitlab.com/ee/development/ee_features.html#code-in-app-views
+ # See https://docs.gitlab.com/ee/development/ee_features.html#code-in-appviews
# rubocop: disable CodeReuse/ActiveRecord
- def render_if_exists(partial, locals = {})
- render(partial, locals) if partial_exists?(partial)
+ # We allow partial to be nil so that collection views can be passed in
+ # `render partial: 'some/view', collection: @some_collection`
+ def render_if_exists(partial = nil, **options)
+ return unless partial_exists?(partial || options[:partial])
+
+ if partial.nil?
+ render(**options)
+ else
+ render(partial, options)
+ end
end
def partial_exists?(partial)
@@ -204,6 +212,10 @@ module ApplicationHelper
Gitlab::CurrentSettings.current_application_settings.help_page_support_url.presence || promo_url + '/getting-help/'
end
+ def instance_review_permitted?
+ ::Gitlab::CurrentSettings.instance_review_permitted? && current_user&.admin?
+ end
+
def static_objects_external_storage_enabled?
Gitlab::CurrentSettings.static_objects_external_storage_enabled?
end
@@ -349,6 +361,12 @@ module ApplicationHelper
}
end
+ def add_page_specific_style(path)
+ content_for :page_specific_styles do
+ stylesheet_link_tag_defer path
+ end
+ end
+
def page_startup_api_calls
@api_startup_calls
end
diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb
index 9245cc1cb1c..9c408efe8cd 100644
--- a/app/helpers/application_settings_helper.rb
+++ b/app/helpers/application_settings_helper.rb
@@ -168,7 +168,7 @@ module ApplicationSettingsHelper
def visible_attributes
[
- :admin_notification_email,
+ :abuse_notification_email,
:after_sign_out_path,
:after_sign_up_text,
:akismet_api_key,
@@ -230,6 +230,7 @@ module ApplicationSettingsHelper
:hashed_storage_enabled,
:help_page_hide_commercial_content,
:help_page_support_url,
+ :help_page_documentation_base_url,
:help_page_text,
:hide_third_party_offers,
:home_page_url,
@@ -265,6 +266,7 @@ module ApplicationSettingsHelper
:receive_max_input_size,
:repository_checks_enabled,
:repository_storages_weighted,
+ :require_admin_approval_after_user_signup,
:require_two_factor_authentication,
:restricted_visibility_levels,
:rsa_key_restriction,
@@ -345,6 +347,12 @@ module ApplicationSettingsHelper
]
end
+ def deprecated_attributes
+ [
+ :admin_notification_email # ok to remove in REST API v5
+ ]
+ end
+
def expanded_by_default?
Rails.env.test?
end
@@ -382,6 +390,10 @@ module ApplicationSettingsHelper
Gitlab::CurrentSettings.self_monitoring_project&.full_path
}
end
+
+ def show_documentation_base_url_field?
+ Feature.enabled?(:help_page_documentation_redirect)
+ end
end
ApplicationSettingsHelper.prepend_if_ee('EE::ApplicationSettingsHelper')
diff --git a/app/helpers/avatars_helper.rb b/app/helpers/avatars_helper.rb
index 68dbc5b65d1..5457f96d506 100644
--- a/app/helpers/avatars_helper.rb
+++ b/app/helpers/avatars_helper.rb
@@ -60,7 +60,7 @@ module AvatarsHelper
avatar_size = options[:size] || 16
user_name = options[:user].try(:name) || options[:user_name]
- avatar_url = user_avatar_url_for(options.merge(size: avatar_size))
+ avatar_url = user_avatar_url_for(**options.merge(size: avatar_size))
has_tooltip = options[:has_tooltip].nil? ? true : options[:has_tooltip]
data_attributes = options[:data] || {}
diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb
index 2eff87ae0ec..806fea3ab44 100644
--- a/app/helpers/blob_helper.rb
+++ b/app/helpers/blob_helper.rb
@@ -1,12 +1,6 @@
# frozen_string_literal: true
module BlobHelper
- def highlight(file_name, file_content, language: nil, plain: false)
- highlighted = Gitlab::Highlight.highlight(file_name, file_content, plain: plain, language: language)
-
- raw %(<pre class="code highlight"><code>#{highlighted}</code></pre>)
- end
-
def no_highlight_files
%w(credits changelog news copying copyright license authors)
end
@@ -33,11 +27,19 @@ module BlobHelper
end
def ide_fork_and_edit_path(project = @project, ref = @ref, path = @path, options = {})
- if current_user
- project_forks_path(project,
- namespace_key: current_user&.namespace&.id,
- continue: edit_blob_fork_params(ide_edit_path(project, ref, path)))
- end
+ fork_path_for_current_user(project, ide_edit_path(project, ref, path))
+ end
+
+ def fork_and_edit_path(project = @project, ref = @ref, path = @path, options = {})
+ fork_path_for_current_user(project, edit_blob_path(project, ref, path, options))
+ end
+
+ def fork_path_for_current_user(project, path)
+ return unless current_user
+
+ project_forks_path(project,
+ namespace_key: current_user.namespace&.id,
+ continue: edit_blob_fork_params(path))
end
def encode_ide_path(path)
@@ -148,7 +150,7 @@ module BlobHelper
# mode - File unix mode
# mode - File name
def blob_icon(mode, name)
- icon("#{file_type_icon_class('file', mode, name)} fw")
+ sprite_icon(file_type_icon_class('file', mode, name))
end
def blob_raw_url(**kwargs)
diff --git a/app/helpers/boards_helper.rb b/app/helpers/boards_helper.rb
index 6a4a7a8dfb2..c827fb4dd95 100644
--- a/app/helpers/boards_helper.rb
+++ b/app/helpers/boards_helper.rb
@@ -14,10 +14,14 @@ module BoardsHelper
root_path: root_path,
full_path: full_path,
bulk_update_path: @bulk_issues_path,
+ can_update: (!!can?(current_user, :admin_issue, board)).to_s,
time_tracking_limit_to_hours: Gitlab::CurrentSettings.time_tracking_limit_to_hours.to_s,
recent_boards_endpoint: recent_boards_path,
parent: current_board_parent.model_name.param_key,
- group_id: @group&.id
+ group_id: @group&.id,
+ labels_filter_base_path: build_issue_link_base,
+ labels_fetch_path: labels_fetch_path,
+ labels_manage_path: labels_manage_path
}
end
@@ -37,6 +41,22 @@ module BoardsHelper
end
end
+ def labels_fetch_path
+ if board.group_board?
+ group_labels_path(@group, format: :json, only_group_labels: true, include_ancestor_groups: true)
+ else
+ project_labels_path(@project, format: :json, include_ancestor_groups: true)
+ end
+ end
+
+ def labels_manage_path
+ if board.group_board?
+ group_labels_path(@group)
+ else
+ project_labels_path(@project)
+ end
+ end
+
def board_base_url
if board.group_board?
group_boards_url(@group)
diff --git a/app/helpers/ci/runners_helper.rb b/app/helpers/ci/runners_helper.rb
index 8cdb28b2874..552acf61f47 100644
--- a/app/helpers/ci/runners_helper.rb
+++ b/app/helpers/ci/runners_helper.rb
@@ -39,6 +39,14 @@ module Ci
runner.contacted_at
end
end
+
+ def group_shared_runners_settings_data(group)
+ {
+ update_path: api_v4_groups_path(id: group.id),
+ shared_runners_availability: group.shared_runners_setting,
+ parent_shared_runners_availability: group.parent&.shared_runners_setting
+ }
+ end
end
end
diff --git a/app/helpers/clusters_helper.rb b/app/helpers/clusters_helper.rb
index caad215e996..cc633df77f9 100644
--- a/app/helpers/clusters_helper.rb
+++ b/app/helpers/clusters_helper.rb
@@ -12,6 +12,18 @@ module ClustersHelper
end
end
+ def display_cluster_agents?(_clusterable)
+ false
+ end
+
+ def js_cluster_agents_list_data(clusterable_project)
+ {
+ default_branch_name: clusterable_project.default_branch,
+ empty_state_image: image_path('illustrations/clusters_empty.svg'),
+ project_path: clusterable_project.full_path
+ }
+ end
+
def js_clusters_list_data(path = nil)
{
ancestor_help_path: help_page_path('user/group/clusters/index', anchor: 'cluster-precedence'),
@@ -42,14 +54,6 @@ module ClustersHelper
}
end
- # This method is depreciated and will be removed when associated HAML files are moved to JavaScript
- def provider_icon(provider = nil)
- img_data = js_clusters_list_data.dig(:img_tags, provider&.to_sym) ||
- js_clusters_list_data.dig(:img_tags, :default)
-
- image_tag img_data[:path], alt: img_data[:text], class: 'gl-h-full'
- end
-
def render_gcp_signup_offer
return if Gitlab::CurrentSettings.current_application_settings.hide_third_party_offers?
return unless show_gcp_signup_offer?
diff --git a/app/helpers/container_expiration_policies_helper.rb b/app/helpers/container_expiration_policies_helper.rb
index cc6d717ce35..52f68ac53f0 100644
--- a/app/helpers/container_expiration_policies_helper.rb
+++ b/app/helpers/container_expiration_policies_helper.rb
@@ -24,4 +24,9 @@ module ContainerExpirationPoliciesHelper
end
end
end
+
+ def container_expiration_policies_historic_entry_enabled?(project)
+ Gitlab::CurrentSettings.container_expiration_policies_enable_historic_entries ||
+ Feature.enabled?(:container_expiration_policies_historic_entry, project)
+ end
end
diff --git a/app/helpers/dropdowns_helper.rb b/app/helpers/dropdowns_helper.rb
index 84aa08281f6..e1378e485e4 100644
--- a/app/helpers/dropdowns_helper.rb
+++ b/app/helpers/dropdowns_helper.rb
@@ -103,7 +103,7 @@ module DropdownsHelper
def dropdown_filter(placeholder, search_id: nil)
content_tag :div, class: "dropdown-input" do
filter_output = search_field_tag search_id, nil, class: "dropdown-input-field qa-dropdown-input-field", placeholder: placeholder, autocomplete: 'off'
- filter_output << icon('search', class: "dropdown-input-search")
+ filter_output << sprite_icon('search', css_class: 'dropdown-input-search')
filter_output << sprite_icon('close', size: 16, css_class: 'dropdown-input-clear js-dropdown-input-clear')
filter_output.html_safe
diff --git a/app/helpers/emails_helper.rb b/app/helpers/emails_helper.rb
index d5c22927991..0a0dc77e5e2 100644
--- a/app/helpers/emails_helper.rb
+++ b/app/helpers/emails_helper.rb
@@ -218,8 +218,28 @@ module EmailsHelper
_('Please contact your administrator with any questions.')
end
+ def change_reviewer_notification_text(new_reviewers, previous_reviewers, html_tag = nil)
+ new = new_reviewers.any? ? users_to_sentence(new_reviewers) : s_('ChangeReviewer|Unassigned')
+ old = previous_reviewers.any? ? users_to_sentence(previous_reviewers) : nil
+
+ if html_tag.present?
+ new = content_tag(html_tag, new)
+ old = content_tag(html_tag, old) if old.present?
+ end
+
+ if old.present?
+ s_('ChangeReviewer|Reviewer changed from %{old} to %{new}').html_safe % { old: old, new: new }
+ else
+ s_('ChangeReviewer|Reviewer changed to %{new}').html_safe % { new: new }
+ end
+ end
+
private
+ def users_to_sentence(users)
+ sanitize_name(users.map(&:name).to_sentence)
+ end
+
def generate_link(text, url)
link_to(text, url, target: :_blank, rel: 'noopener noreferrer')
end
diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb
index 0167f2ef698..f40755b9439 100644
--- a/app/helpers/events_helper.rb
+++ b/app/helpers/events_helper.rb
@@ -28,19 +28,7 @@ module EventsHelper
end
def event_action_name(event)
- target = if event.target_type
- if event.design? || event.design_note?
- 'design'
- elsif event.wiki_page?
- 'wiki page'
- elsif event.note?
- event.note_target_type
- else
- event.target_type.titleize.downcase
- end
- else
- 'project'
- end
+ target = event.note_target_type_name || event.target_type_name
[event.action_name, target].join(" ")
end
@@ -229,7 +217,7 @@ module EventsHelper
def event_note_title_html(event)
if event.note_target
capture do
- concat content_tag(:span, event.note_target_type, class: "event-target-type gl-mr-2")
+ concat content_tag(:span, event.note_target_type_name, class: "event-target-type gl-mr-2")
concat link_to(event.note_target_reference, event_note_target_url(event), title: event.target_title, class: 'has-tooltip event-target-link gl-mr-2')
end
else
diff --git a/app/helpers/external_link_helper.rb b/app/helpers/external_link_helper.rb
index 9dbad1f5032..bf47087543f 100644
--- a/app/helpers/external_link_helper.rb
+++ b/app/helpers/external_link_helper.rb
@@ -3,7 +3,7 @@
module ExternalLinkHelper
def external_link(body, url, options = {})
link_to url, { target: '_blank', rel: 'noopener noreferrer' }.merge(options) do
- "#{body} #{icon('external-link')}".html_safe
+ "#{body} #{sprite_icon('external-link')}".html_safe
end
end
end
diff --git a/app/helpers/feature_flags_helper.rb b/app/helpers/feature_flags_helper.rb
new file mode 100644
index 00000000000..e50191a471f
--- /dev/null
+++ b/app/helpers/feature_flags_helper.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module FeatureFlagsHelper
+ include ::API::Helpers::RelatedResourcesHelpers
+
+ def unleash_api_url(project)
+ expose_url(api_v4_feature_flags_unleash_path(project_id: project.id))
+ end
+
+ def unleash_api_instance_id(project)
+ project.feature_flags_client_token
+ end
+
+ def feature_flag_issues_links_endpoint(_project, _feature_flag, _user)
+ ''
+ end
+end
+
+FeatureFlagsHelper.prepend_if_ee('::EE::FeatureFlagsHelper')
diff --git a/app/helpers/form_helper.rb b/app/helpers/form_helper.rb
index 3dde5afcb92..8a8d708b0b2 100644
--- a/app/helpers/form_helper.rb
+++ b/app/helpers/form_helper.rb
@@ -56,7 +56,7 @@ module FormHelper
end
def reviewers_dropdown_options(issuable_type)
- {
+ dropdown_data = {
toggle_class: 'js-reviewer-search js-multiselect js-save-user-data',
title: 'Request review from',
filter: true,
@@ -69,13 +69,20 @@ module FormHelper
project_id: (@target_project || @project)&.id,
field_name: "#{issuable_type}[reviewer_ids][]",
default_label: 'Unassigned',
- 'dropdown-header': 'Reviewer(s)',
+ 'max-select': 1,
+ 'dropdown-header': 'Reviewer',
multi_select: true,
'input-meta': 'name',
'always-show-selectbox': true,
current_user_info: UserSerializer.new.represent(current_user)
}
}
+
+ if merge_request_supports_multiple_reviewers?
+ dropdown_data = multiple_reviewers_dropdown_options(dropdown_data)
+ end
+
+ dropdown_data
end
# Overwritten
@@ -88,6 +95,11 @@ module FormHelper
false
end
+ # Overwritten
+ def merge_request_supports_multiple_reviewers?
+ false
+ end
+
private
def multiple_assignees_dropdown_options(options)
@@ -99,6 +111,16 @@ module FormHelper
new_options
end
+
+ def multiple_reviewers_dropdown_options(options)
+ new_options = options.dup
+
+ new_options[:title] = _('Select reviewer(s)')
+ new_options[:data][:'dropdown-header'] = _('Reviewer(s)')
+ new_options[:data].delete(:'max-select')
+
+ new_options
+ end
end
FormHelper.prepend_if_ee('::EE::FormHelper')
diff --git a/app/helpers/gitlab_routing_helper.rb b/app/helpers/gitlab_routing_helper.rb
index d71e6b4c004..7df6bef7914 100644
--- a/app/helpers/gitlab_routing_helper.rb
+++ b/app/helpers/gitlab_routing_helper.rb
@@ -343,6 +343,18 @@ module GitlabRoutingHelper
Gitlab::UrlBuilder.wiki_page_url(wiki, page, only_path: true, **options)
end
+ def gitlab_ide_merge_request_path(merge_request)
+ target_project = merge_request.target_project
+ source_project = merge_request.source_project
+ params = {}
+
+ if target_project != source_project
+ params = { target_project: target_project.full_path }
+ end
+
+ ide_merge_request_path(source_project.namespace, source_project, merge_request, params)
+ end
+
private
def snippet_query_params(snippet, *args)
diff --git a/app/helpers/gitpod_helper.rb b/app/helpers/gitpod_helper.rb
new file mode 100644
index 00000000000..7edf7dc218d
--- /dev/null
+++ b/app/helpers/gitpod_helper.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+module GitpodHelper
+ def gitpod_enable_description
+ link_start = '<a href="https://gitpod.io/" target="_blank" rel="noopener noreferrer">'.html_safe
+ link_end = "#{sprite_icon('external-link', size: 12, css_class: 'ml-1 vertical-align-center')}</a>".html_safe
+
+ s_('Enable %{link_start}Gitpod%{link_end} integration to launch a development environment in your browser directly from GitLab.').html_safe % { link_start: link_start, link_end: link_end }
+ end
+end
diff --git a/app/helpers/groups/group_members_helper.rb b/app/helpers/groups/group_members_helper.rb
index dcff2be34da..ee90585112b 100644
--- a/app/helpers/groups/group_members_helper.rb
+++ b/app/helpers/groups/group_members_helper.rb
@@ -10,17 +10,34 @@ module Groups::GroupMembersHelper
end
def render_invite_member_for_group(group, default_access_level)
- render 'shared/members/invite_member', submit_url: group_group_members_path(group), access_levels: GroupMember.access_level_roles, default_access_level: default_access_level
+ render 'shared/members/invite_member', submit_url: group_group_members_path(group), access_levels: group.access_level_roles, default_access_level: default_access_level
end
def linked_groups_data_json(group_links)
- GroupGroupLinkSerializer.new.represent(group_links).to_json
+ GroupGroupLinkSerializer.new.represent(group_links, { current_user: current_user }).to_json
end
def members_data_json(group, members)
members_data(group, members).to_json
end
+ # Overridden in `ee/app/helpers/ee/groups/group_members_helper.rb`
+ def group_members_list_data_attributes(group, members)
+ {
+ members: members_data_json(group, members),
+ member_path: group_group_member_path(group, ':id'),
+ group_id: group.id
+ }
+ end
+
+ def linked_groups_list_data_attributes(group)
+ {
+ members: linked_groups_data_json(group.shared_with_group_links),
+ member_path: group_group_link_path(group, ':id'),
+ group_id: group.id
+ }
+ end
+
private
def members_data(group, members)
@@ -35,7 +52,6 @@ module Groups::GroupMembersHelper
requested_at: member.requested_at,
can_update: member.can_update?,
can_remove: member.can_remove?,
- can_override: member.can_override?,
access_level: {
string_value: member.human_access,
integer_value: member.access_level
@@ -44,13 +60,14 @@ module Groups::GroupMembersHelper
id: source.id,
name: source.full_name,
web_url: Gitlab::UrlBuilder.build(source)
- }
+ },
+ valid_roles: member.valid_level_roles
}.merge(member_created_by_data(member.created_by))
- if user.present?
- data[:user] = member_user_data(user)
- else
+ if member.invite?
data[:invite] = member_invite_data(member)
+ elsif user.present?
+ data[:user] = member_user_data(user)
end
data
@@ -77,6 +94,17 @@ module Groups::GroupMembersHelper
avatar_url: avatar_icon_for_user(user, AVATAR_SIZE),
blocked: user.blocked?,
two_factor_enabled: user.two_factor_enabled?
+ }.merge(member_user_status_data(user.status))
+ end
+
+ def member_user_status_data(status)
+ return {} unless status.present?
+
+ {
+ status: {
+ emoji: status.emoji,
+ message_html: status.message_html
+ }
}
end
diff --git a/app/helpers/icons_helper.rb b/app/helpers/icons_helper.rb
index 0352b0ddf28..1d0001fde72 100644
--- a/app/helpers/icons_helper.rb
+++ b/app/helpers/icons_helper.rb
@@ -124,7 +124,7 @@ module IconsHelper
def file_type_icon_class(type, mode, name)
if type == 'folder'
- icon_class = 'folder'
+ icon_class = 'folder-o'
elsif type == 'archive'
icon_class = 'archive'
elsif mode == '120000'
@@ -135,36 +135,36 @@ module IconsHelper
case File.extname(name).downcase
when '.pdf'
- icon_class = 'file-pdf-o'
+ icon_class = 'document'
when '.jpg', '.jpeg', '.jif', '.jfif',
'.jp2', '.jpx', '.j2k', '.j2c',
'.apng', '.png', '.gif', '.tif', '.tiff',
'.svg', '.ico', '.bmp', '.webp'
- icon_class = 'file-image-o'
+ icon_class = 'doc-image'
when '.zip', '.zipx', '.tar', '.gz', '.gzip', '.tgz', '.bz', '.bzip',
'.bz2', '.bzip2', '.car', '.tbz', '.xz', 'txz', '.rar', '.7z',
'.lz', '.lzma', '.tlz'
- icon_class = 'file-archive-o'
+ icon_class = 'doc-compressed'
when '.mp3', '.wma', '.ogg', '.oga', '.wav', '.flac', '.aac', '.3ga',
'.ac3', '.midi', '.m4a', '.ape', '.mpa'
- icon_class = 'file-audio-o'
+ icon_class = 'volume-up'
when '.mp4', '.m4p', '.m4v',
'.mpg', '.mp2', '.mpeg', '.mpe', '.mpv',
'.mpg', '.mpeg', '.m2v', '.m2ts',
'.avi', '.mkv', '.flv', '.ogv', '.mov',
'.3gp', '.3g2'
- icon_class = 'file-video-o'
+ icon_class = 'live-preview'
when '.doc', '.dot', '.docx', '.docm', '.dotx', '.dotm', '.docb',
'.odt', '.ott', '.uot', '.rtf'
- icon_class = 'file-word-o'
+ icon_class = 'doc-text'
when '.xls', '.xlt', '.xlm', '.xlsx', '.xlsm', '.xltx', '.xltm',
'.xlsb', '.xla', '.xlam', '.xll', '.xlw', '.ots', '.ods', '.uos'
- icon_class = 'file-excel-o'
+ icon_class = 'document'
when '.ppt', '.pot', '.pps', '.pptx', '.pptm', '.potx', '.potm',
'.ppam', '.ppsx', '.ppsm', '.sldx', '.sldm', '.odp', '.otp', '.uop'
- icon_class = 'file-powerpoint-o'
+ icon_class = 'doc-chart'
else
- icon_class = 'file-text-o'
+ icon_class = 'doc-text'
end
end
diff --git a/app/helpers/invite_members_helper.rb b/app/helpers/invite_members_helper.rb
new file mode 100644
index 00000000000..ac6ac9979b3
--- /dev/null
+++ b/app/helpers/invite_members_helper.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module InviteMembersHelper
+ include Gitlab::Utils::StrongMemoize
+
+ def invite_members_allowed?(group)
+ Feature.enabled?(:invite_members_group_modal, group) && can?(current_user, :admin_group_member, group)
+ end
+
+ def directly_invite_members?
+ strong_memoize(:directly_invite_members) do
+ experiment_enabled?(:invite_members_version_a) && can_import_members?
+ end
+ end
+
+ def indirectly_invite_members?
+ strong_memoize(:indirectly_invite_members) do
+ experiment_enabled?(:invite_members_version_b) && !can_import_members?
+ end
+ end
+end
diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb
index b255597b18d..f8e7711959a 100644
--- a/app/helpers/issuables_helper.rb
+++ b/app/helpers/issuables_helper.rb
@@ -4,7 +4,10 @@ module IssuablesHelper
include GitlabRoutingHelper
def sidebar_gutter_toggle_icon
- sidebar_gutter_collapsed? ? icon('angle-double-left', { 'aria-hidden': 'true' }) : icon('angle-double-right', { 'aria-hidden': 'true' })
+ content_tag(:span, class: 'js-sidebar-toggle-container', data: { is_expanded: !sidebar_gutter_collapsed? }) do
+ sprite_icon('chevron-double-lg-left', css_class: "js-sidebar-expand #{'hidden' unless sidebar_gutter_collapsed?}") +
+ sprite_icon('chevron-double-lg-right', css_class: "js-sidebar-collapse #{'hidden' if sidebar_gutter_collapsed?}")
+ end
end
def sidebar_gutter_collapsed_class
@@ -46,12 +49,6 @@ module IssuablesHelper
"#{due_date.to_s(:medium)} (#{remaining_days_in_words(due_date, start_date)})"
end
- def sidebar_label_filter_path(base_path, label_name)
- query_params = { label_name: [label_name] }.to_query
-
- "#{base_path}?#{query_params}"
- end
-
def multi_label_name(current_labels, default_label)
return default_label if current_labels.blank?
@@ -79,6 +76,7 @@ module IssuablesHelper
when Issue
IssueSerializer
when MergeRequest
+ opts[:experiment_enabled] = :suggest_pipeline if experiment_enabled?(:suggest_pipeline) && opts[:serializer] == 'widget'
MergeRequestSerializer
end
@@ -206,7 +204,7 @@ module IssuablesHelper
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 is a %{access} of the %{name} project.") % { access: access.downcase, name: project.name })
+ 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
@@ -224,19 +222,6 @@ module IssuablesHelper
nil
end
- def issuable_labels_tooltip(labels, limit: 5)
- first, last = labels.partition.with_index { |_, i| i < limit }
-
- if labels && labels.any?
- label_names = first.collect { |label| label.fetch(:title) }
- label_names << "and #{last.size} more" unless last.empty?
-
- label_names.join(', ')
- else
- _("Labels")
- end
- end
-
def issuables_state_counter_text(issuable_type, state, display_count)
titles = {
opened: "Open"
@@ -247,7 +232,22 @@ module IssuablesHelper
if display_count
count = issuables_count_for_state(issuable_type, state)
- html << " " << content_tag(:span, number_with_delimiter(count), class: 'badge badge-pill')
+ tag =
+ if count == -1
+ tooltip = _("Couldn't calculate number of %{issuables}.") % { issuables: issuable_type.to_s.humanize(capitalize: false) }
+
+ content_tag(
+ :span,
+ '?',
+ class: 'badge badge-pill has-tooltip',
+ aria: { label: tooltip },
+ title: tooltip
+ )
+ else
+ content_tag(:span, number_with_delimiter(count), class: 'badge badge-pill')
+ end
+
+ html << " " << tag
end
html.html_safe
@@ -342,6 +342,12 @@ module IssuablesHelper
issuable.closed? ^ should_inverse ? reopen_issuable_path(issuable) : close_issuable_path(issuable)
end
+ def toggle_draft_issuable_path(issuable)
+ wip_event = issuable.work_in_progress? ? 'unwip' : 'wip'
+
+ issuable_path(issuable, { merge_request: { wip_event: wip_event } })
+ end
+
def issuable_path(issuable, *options)
polymorphic_path(issuable, *options)
end
@@ -386,6 +392,12 @@ 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
@@ -420,7 +432,7 @@ module IssuablesHelper
def issuable_todo_button_data(issuable, is_collapsed)
{
- todo_text: _('Add a To Do'),
+ 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'),
diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb
index e8ea39d7ffc..dbf284e70e4 100644
--- a/app/helpers/issues_helper.rb
+++ b/app/helpers/issues_helper.rb
@@ -137,6 +137,21 @@ module IssuesHelper
issue.moved_from.project.service_desk_enabled? && !issue.project.service_desk_enabled?
end
+
+ def use_startup_call?
+ request.query_parameters.empty? && @sort == 'created_date'
+ end
+
+ def startup_call_params
+ {
+ state: 'opened',
+ with_labels_details: 'true',
+ page: 1,
+ per_page: 20,
+ order_by: 'created_at',
+ sort: 'desc'
+ }
+ end
end
IssuesHelper.prepend_if_ee('EE::IssuesHelper')
diff --git a/app/helpers/labels_helper.rb b/app/helpers/labels_helper.rb
index 3142d7d7782..312d535a92c 100644
--- a/app/helpers/labels_helper.rb
+++ b/app/helpers/labels_helper.rb
@@ -36,11 +36,11 @@ module LabelsHelper
# link_to_label(label) { "My Custom Label Text" }
#
# Returns a String
- def link_to_label(label, type: :issue, tooltip: true, small: false, &block)
+ def link_to_label(label, type: :issue, tooltip: true, small: false, css_class: nil, &block)
link = label.filter_path(type: type)
if block_given?
- link_to link, &block
+ link_to link, class: css_class, &block
else
render_label(label, link: link, tooltip: tooltip, small: small)
end
@@ -61,7 +61,7 @@ module LabelsHelper
render_label_text(
label.name,
suffix: suffix,
- css_class: text_color_class_for_bg(label.color),
+ css_class: "gl-label-text #{text_color_class_for_bg(label.color)}",
bg_color: label.color
)
end
@@ -241,29 +241,14 @@ module LabelsHelper
}.merge(opts)
end
- def sidebar_label_dropdown_data(issuable_type, issuable_sidebar)
- label_dropdown_data(nil, {
- default_label: "Labels",
- field_name: "#{issuable_type}[label_names][]",
- ability_name: issuable_type,
- namespace_path: issuable_sidebar[:namespace_path],
- project_path: issuable_sidebar[:project_path],
- issue_update: issuable_sidebar[:issuable_json_path],
- labels: issuable_sidebar[:project_labels_path],
- display: 'static'
- })
- end
-
- def label_from_hash(hash)
- klass = hash[:group_id] ? GroupLabel : ProjectLabel
-
- klass.new(hash.slice(:color, :description, :title, :group_id, :project_id))
- end
-
def issuable_types
['issues', 'merge requests']
end
+ def show_labels_full_path?(project, group)
+ project || group&.subgroup?
+ end
+
private
def render_label_link(label_html, link:, title:, dataset:)
@@ -281,7 +266,7 @@ module LabelsHelper
def render_label_text(name, suffix: '', css_class: nil, bg_color: nil)
<<~HTML.chomp.html_safe
<span
- class="gl-label-text #{css_class}"
+ class="#{css_class}"
data-container="body"
data-html="true"
#{"style=\"background-color: #{bg_color}\"" if bg_color}
diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb
index 1125ecb9b41..9cb7edbaeb6 100644
--- a/app/helpers/merge_requests_helper.rb
+++ b/app/helpers/merge_requests_helper.rb
@@ -109,10 +109,6 @@ module MergeRequestsHelper
@merge_request_diffs.size - @merge_request_diffs.index(merge_request_diff)
end
- def different_base?(version1, version2)
- version1 && version2 && version1.base_commit_sha != version2.base_commit_sha
- end
-
def merge_params(merge_request)
{
auto_merge_strategy: AutoMergeService::STRATEGY_MERGE_WHEN_PIPELINE_SUCCEEDS,
diff --git a/app/helpers/mirror_helper.rb b/app/helpers/mirror_helper.rb
index 50fc5e521fc..9d23ab87b98 100644
--- a/app/helpers/mirror_helper.rb
+++ b/app/helpers/mirror_helper.rb
@@ -9,7 +9,11 @@ module MirrorHelper
end
def mirror_lfs_sync_message
- html_escape(_('The Git LFS objects will %{strong_open}not%{strong_close} be synced.')) % { strong_open: '<strong>'.html_safe, strong_close: '</strong>'.html_safe }
+ docs_link_url = help_page_path('topics/git/lfs/index')
+ docs_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: docs_link_url }
+
+ html_escape(_('Git LFS objects will be synced if LFS is %{docs_link_start}enabled for the project%{docs_link_end}. Push mirrors will %{strong_open}not%{strong_close} sync LFS objects over SSH.')) %
+ { docs_link_start: docs_link_start, docs_link_end: '</a>'.html_safe, strong_open: '<strong>'.html_safe, strong_close: '</strong>'.html_safe }
end
end
diff --git a/app/helpers/namespaces_helper.rb b/app/helpers/namespaces_helper.rb
index 81451e398f2..8cf5cd49322 100644
--- a/app/helpers/namespaces_helper.rb
+++ b/app/helpers/namespaces_helper.rb
@@ -53,7 +53,7 @@ module NamespacesHelper
selected = options.delete(:selected) || :current_user
options[:groups] = current_user.manageable_groups_with_routes(include_groups_with_developer_maintainer_access: true)
- namespaces_options(selected, options)
+ namespaces_options(selected, **options)
end
private
diff --git a/app/helpers/nav_helper.rb b/app/helpers/nav_helper.rb
index 578c7ae7923..3c757a4ef26 100644
--- a/app/helpers/nav_helper.rb
+++ b/app/helpers/nav_helper.rb
@@ -55,7 +55,8 @@ module NavHelper
current_path?('projects/merge_requests/conflicts#show') ||
current_path?('issues#show') ||
current_path?('milestones#show') ||
- current_path?('issues#designs')
+ current_path?('issues#designs') ||
+ current_path?('incidents#show')
end
def admin_monitoring_nav_links
diff --git a/app/helpers/operations_helper.rb b/app/helpers/operations_helper.rb
index 521f394a920..9965a705a01 100644
--- a/app/helpers/operations_helper.rb
+++ b/app/helpers/operations_helper.rb
@@ -27,7 +27,7 @@ module OperationsHelper
'authorization_key' => alerts_service.token,
'prometheus_url' => notify_project_prometheus_alerts_url(@project, format: :json),
'url' => alerts_service.url,
- 'alerts_setup_url' => help_page_path('user/project/integrations/generic_alerts.md', anchor: 'setting-up-generic-alerts'),
+ 'alerts_setup_url' => help_page_path('operations/incident_management/alert_integrations.md', anchor: 'generic-http-endpoint'),
'alerts_usage_url' => project_alert_management_index_path(@project),
'disabled' => disabled.to_s
}
diff --git a/app/helpers/packages_helper.rb b/app/helpers/packages_helper.rb
index e6ecc403a88..8f365fd0786 100644
--- a/app/helpers/packages_helper.rb
+++ b/app/helpers/packages_helper.rb
@@ -34,26 +34,22 @@ module PackagesHelper
expose_url(api_v4_group___packages_composer_packages_path(id: group_id, format: '.json'))
end
- def packages_coming_soon_enabled?(resource)
- ::Feature.enabled?(:packages_coming_soon, resource) && ::Gitlab.dev_env_or_com?
- end
-
- def packages_coming_soon_data(resource)
- return unless packages_coming_soon_enabled?(resource)
-
- {
- project_path: ::Gitlab.com? ? 'gitlab-org/gitlab' : 'gitlab-org/gitlab-test',
- suggested_contributions: help_page_path('user/packages/index', anchor: 'suggested-contributions')
- }
+ def composer_config_repository_name(group_id)
+ "#{Gitlab.config.gitlab.host}/#{group_id}"
end
def packages_list_data(type, resource)
{
resource_id: resource.id,
page_type: type,
- empty_list_help_url: help_page_path('administration/packages/index'),
+ empty_list_help_url: help_page_path('user/packages/package_registry/index'),
empty_list_illustration: image_path('illustrations/no-packages.svg'),
- coming_soon_json: packages_coming_soon_data(resource).to_json
+ package_help_url: help_page_path('user/packages/index')
}
end
+
+ def track_package_event(event_name, scope, **args)
+ ::Packages::CreateEventService.new(nil, current_user, event_name: event_name, scope: scope).execute
+ track_event(event_name, **args)
+ end
end
diff --git a/app/helpers/page_layout_helper.rb b/app/helpers/page_layout_helper.rb
index a44760e85ca..6808ffc3e27 100644
--- a/app/helpers/page_layout_helper.rb
+++ b/app/helpers/page_layout_helper.rb
@@ -40,6 +40,14 @@ module PageLayoutHelper
end
end
+ def page_canonical_link(link = nil)
+ if link
+ @page_canonical_link = link
+ else
+ @page_canonical_link
+ end
+ end
+
def favicon
Gitlab::Favicon.main
end
diff --git a/app/helpers/pagination_helper.rb b/app/helpers/pagination_helper.rb
index d05153c9d4b..3167142e193 100644
--- a/app/helpers/pagination_helper.rb
+++ b/app/helpers/pagination_helper.rb
@@ -1,11 +1,13 @@
# frozen_string_literal: true
module PaginationHelper
- def paginate_collection(collection, remote: nil)
+ # total_pages will be inferred from the collection if nil. It is ignored if
+ # the collection is a Kaminari::PaginatableWithoutCount
+ def paginate_collection(collection, remote: nil, total_pages: nil)
if collection.is_a?(Kaminari::PaginatableWithoutCount)
paginate_without_count(collection)
elsif collection.respond_to?(:total_pages)
- paginate_with_count(collection, remote: remote)
+ paginate_with_count(collection, remote: remote, total_pages: total_pages)
end
end
@@ -17,7 +19,7 @@ module PaginationHelper
)
end
- def paginate_with_count(collection, remote: nil)
- paginate(collection, remote: remote, theme: 'gitlab')
+ def paginate_with_count(collection, remote: nil, total_pages: nil)
+ paginate(collection, remote: remote, theme: 'gitlab', total_pages: total_pages)
end
end
diff --git a/app/helpers/preferences_helper.rb b/app/helpers/preferences_helper.rb
index 2c406641882..9bf819febb0 100644
--- a/app/helpers/preferences_helper.rb
+++ b/app/helpers/preferences_helper.rb
@@ -61,8 +61,8 @@ module PreferencesHelper
@user_application_theme ||= Gitlab::Themes.for_user(current_user).css_class
end
- def user_application_theme_name
- @user_application_theme_name ||= Gitlab::Themes.for_user(current_user).name.downcase.tr(' ', '_')
+ def user_application_theme_css_filename
+ @user_application_theme_css_filename ||= Gitlab::Themes.for_user(current_user).css_filename
end
def user_color_scheme
diff --git a/app/helpers/projects/alert_management_helper.rb b/app/helpers/projects/alert_management_helper.rb
index c2f0b8854e1..5ce3736c8ef 100644
--- a/app/helpers/projects/alert_management_helper.rb
+++ b/app/helpers/projects/alert_management_helper.rb
@@ -9,7 +9,9 @@ module Projects::AlertManagementHelper
'populating-alerts-help-url' => help_page_url('operations/incident_management/index.md', anchor: 'enable-alert-management'),
'empty-alert-svg-path' => image_path('illustrations/alert-management-empty-state.svg'),
'user-can-enable-alert-management' => can?(current_user, :admin_operations, project).to_s,
- 'alert-management-enabled' => alert_management_enabled?(project).to_s
+ 'alert-management-enabled' => alert_management_enabled?(project).to_s,
+ 'text-query': params[:search],
+ 'assignee-username-query': params[:assignee_username]
}
end
diff --git a/app/helpers/projects/incidents_helper.rb b/app/helpers/projects/incidents_helper.rb
index e96f0f5a384..63504cb55b9 100644
--- a/app/helpers/projects/incidents_helper.rb
+++ b/app/helpers/projects/incidents_helper.rb
@@ -1,14 +1,17 @@
# frozen_string_literal: true
module Projects::IncidentsHelper
- def incidents_data(project)
+ def incidents_data(project, params)
{
'project-path' => project.full_path,
'new-issue-path' => new_project_issue_path(project),
'incident-template-name' => 'incident',
'incident-type' => 'incident',
'issue-path' => project_issues_path(project),
- 'empty-list-svg-path' => image_path('illustrations/incident-empty-state.svg')
+ 'empty-list-svg-path' => image_path('illustrations/incident-empty-state.svg'),
+ 'text-query': params[:search],
+ 'author-username-query': params[:author_username],
+ 'assignee-username-query': params[:assignee_username]
}
end
end
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index 72cc07b13a5..ae46135e890 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -301,7 +301,6 @@ module ProjectsHelper
!disabled && !compact_mode
end
- # overridden in EE
def settings_operations_available?
can?(current_user, :read_environment, @project)
end
@@ -468,16 +467,25 @@ module ProjectsHelper
serverless: :read_cluster,
error_tracking: :read_sentry_issue,
alert_management: :read_alert_management_alert,
- incidents: :read_incidents,
+ incidents: :read_issue,
labels: :read_label,
issues: :read_issue,
project_members: :read_project_member,
- wiki: :read_wiki
+ wiki: :read_wiki,
+ feature_flags: :read_feature_flag
}
end
def can_view_operations_tab?(current_user, project)
- [:read_environment, :read_cluster, :metrics_dashboard].any? do |ability|
+ [
+ :metrics_dashboard,
+ :read_alert_management_alert,
+ :read_environment,
+ :read_issue,
+ :read_sentry_issue,
+ :read_cluster,
+ :read_feature_flag
+ ].any? do |ability|
can?(current_user, ability, project)
end
end
@@ -555,7 +563,11 @@ module ProjectsHelper
end
def sidebar_operations_link_path(project = @project)
- metrics_project_environments_path(project) if can?(current_user, :read_environment, project)
+ if can?(current_user, :read_environment, project)
+ metrics_project_environments_path(project)
+ else
+ project_feature_flags_path(project)
+ end
end
def project_last_activity(project)
@@ -748,6 +760,8 @@ module ProjectsHelper
logs
product_analytics
metrics_dashboard
+ feature_flags
+ tracings
]
end
@@ -758,10 +772,6 @@ module ProjectsHelper
!project.repository.gitlab_ci_yml
end
- def native_code_navigation_enabled?(project)
- Feature.enabled?(:code_navigation, project, default_enabled: true)
- end
-
def show_visibility_confirm_modal?(project)
project.unlink_forks_upon_visibility_decrease_enabled? && project.visibility_level > Gitlab::VisibilityLevel::PRIVATE && project.forks_count > 0
end
@@ -772,9 +782,7 @@ module ProjectsHelper
end
def project_access_token_available?(project)
- return false if ::Gitlab.com?
-
- ::Feature.enabled?(:resource_access_token, project, default_enabled: true)
+ can?(current_user, :admin_resource_access_tokens, project)
end
end
diff --git a/app/helpers/releases_helper.rb b/app/helpers/releases_helper.rb
index 979a68ecb7b..050b27840a0 100644
--- a/app/helpers/releases_helper.rb
+++ b/app/helpers/releases_helper.rb
@@ -29,6 +29,14 @@ module ReleasesHelper
end
end
+ def data_for_show_page
+ {
+ project_id: @project.id,
+ project_path: @project.full_path,
+ tag_name: @release.tag
+ }
+ end
+
def data_for_edit_release_page
new_edit_pages_shared_data.merge(
tag_name: @release.tag,
@@ -48,6 +56,7 @@ module ReleasesHelper
def new_edit_pages_shared_data
{
project_id: @project.id,
+ project_path: @project.full_path,
markdown_preview_path: preview_markdown_path(@project),
markdown_docs_path: help_page_path('user/markdown'),
update_release_api_docs_path: help_page_path('api/releases/index.md', anchor: 'update-a-release'),
diff --git a/app/helpers/reminder_emails_helper.rb b/app/helpers/reminder_emails_helper.rb
new file mode 100644
index 00000000000..bffb3cf7751
--- /dev/null
+++ b/app/helpers/reminder_emails_helper.rb
@@ -0,0 +1,76 @@
+# frozen_string_literal: true
+
+module ReminderEmailsHelper
+ def invitation_reminder_salutation(reminder_index, format: nil)
+ case reminder_index
+ when 0
+ s_('InviteReminderEmail|Invitation pending')
+ when 1
+ if format == :html
+ s_('InviteReminderEmail|Hey there %{wave_emoji}').html_safe % { wave_emoji: Gitlab::Emoji.gl_emoji_tag('wave') }
+ else
+ s_('InviteReminderEmail|Hey there!')
+ end
+ when 2
+ s_('InviteReminderEmail|In case you missed it...')
+ end
+ end
+
+ def invitation_reminder_body(member, reminder_index, format: nil)
+ options = {
+ inviter: sanitize_name(member.created_by.name),
+ strong_start: '',
+ strong_end: '',
+ project_or_group_name: member_source.human_name,
+ project_or_group: member_source.model_name.singular,
+ role: member.human_access.downcase
+ }
+
+ if format == :html
+ options.merge!(
+ inviter: (link_to member.created_by.name, user_url(member.created_by)).html_safe,
+ strong_start: '<strong>'.html_safe,
+ strong_end: '</strong>'.html_safe
+ )
+ end
+
+ if reminder_index == 2
+ options[:invitation_age] = (Date.current - member.created_at.to_date).to_i
+ end
+
+ body = invitation_reminder_body_text(reminder_index)
+
+ (format == :html ? html_escape(body) : body ) % options
+ end
+
+ def invitation_reminder_accept_link(token, format: nil)
+ case format
+ when :html
+ link_to s_('InviteReminderEmail|Accept invitation'), invite_url(token), class: 'invite-btn-join'
+ else
+ s_('InviteReminderEmail|Accept invitation: %{invite_url}') % { invite_url: invite_url(token) }
+ end
+ end
+
+ def invitation_reminder_decline_link(token, format: nil)
+ case format
+ when :html
+ link_to s_('InviteReminderEmail|Decline invitation'), decline_invite_url(token), class: 'invite-btn-decline'
+ else
+ s_('InviteReminderEmail|Decline invitation: %{decline_url}') % { decline_url: decline_invite_url(token) }
+ end
+ end
+
+ private
+
+ def invitation_reminder_body_text(reminder_index)
+ case reminder_index
+ when 0
+ s_('InviteReminderEmail|%{inviter} is waiting for you to join the %{strong_start}%{project_or_group_name}%{strong_end} %{project_or_group} as a %{role}.')
+ when 1
+ s_('InviteReminderEmail|This is a friendly reminder that %{inviter} invited you to join the %{strong_start}%{project_or_group_name}%{strong_end} %{project_or_group} as a %{role}.')
+ when 2
+ s_("InviteReminderEmail|It's been %{invitation_age} days since %{inviter} invited you to join the %{strong_start}%{project_or_group_name}%{strong_end} %{project_or_group} as a %{role}. What would you like to do?")
+ end
+ end
+end
diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb
index d55ad878b92..3467f6e9a44 100644
--- a/app/helpers/search_helper.rb
+++ b/app/helpers/search_helper.rb
@@ -1,14 +1,13 @@
# frozen_string_literal: true
module SearchHelper
- SEARCH_PERMITTED_PARAMS = [:search, :scope, :project_id, :group_id, :repository_ref, :snippets, :state].freeze
+ SEARCH_PERMITTED_PARAMS = [:search, :scope, :project_id, :group_id, :repository_ref, :snippets, :sort, :state, :confidential].freeze
def search_autocomplete_opts(term)
return unless current_user
resources_results = [
- recent_merge_requests_autocomplete(term),
- recent_issues_autocomplete(term),
+ recent_items_autocomplete(term),
groups_autocomplete(term),
projects_autocomplete(term)
].flatten
@@ -27,6 +26,10 @@ module SearchHelper
end
end
+ def recent_items_autocomplete(term)
+ recent_merge_requests_autocomplete(term) + recent_issues_autocomplete(term)
+ end
+
def search_entries_info(collection, scope, term)
return if collection.to_a.empty?
@@ -86,13 +89,18 @@ module SearchHelper
}).html_safe
end
+ def repository_ref(project)
+ # Always #to_s the repository_ref param in case the value is also a number
+ params[:repository_ref].to_s.presence || project.default_branch
+ end
+
# Overridden in EE
def search_blob_title(project, path)
path
end
def search_service
- @search_service ||= ::SearchService.new(current_user, params)
+ @search_service ||= ::SearchService.new(current_user, params.merge(confidential: Gitlab::Utils.to_boolean(params[:confidential])))
end
private
@@ -123,8 +131,7 @@ module SearchHelper
{ category: "Help", label: _("Rake Tasks Help"), url: help_page_path("raketasks/README") },
{ category: "Help", label: _("SSH Keys Help"), url: help_page_path("ssh/README") },
{ category: "Help", label: _("System Hooks Help"), url: help_page_path("system_hooks/system_hooks") },
- { category: "Help", label: _("Webhooks Help"), url: help_page_path("user/project/integrations/webhooks") },
- { category: "Help", label: _("Workflow Help"), url: help_page_path("workflow/README") }
+ { category: "Help", label: _("Webhooks Help"), url: help_page_path("user/project/integrations/webhooks") }
]
end
@@ -181,10 +188,10 @@ module SearchHelper
end
end
- def recent_merge_requests_autocomplete(term, limit = 5)
+ def recent_merge_requests_autocomplete(term)
return [] unless current_user
- ::Gitlab::Search::RecentMergeRequests.new(user: current_user).search(term).limit(limit).map do |mr|
+ ::Gitlab::Search::RecentMergeRequests.new(user: current_user).search(term).map do |mr|
{
category: "Recent merge requests",
id: mr.id,
@@ -195,10 +202,10 @@ module SearchHelper
end
end
- def recent_issues_autocomplete(term, limit = 5)
+ def recent_issues_autocomplete(term)
return [] unless current_user
- ::Gitlab::Search::RecentIssues.new(user: current_user).search(term).limit(limit).map do |i|
+ ::Gitlab::Search::RecentIssues.new(user: current_user).search(term).map do |i|
{
category: "Recent issues",
id: i.id,
@@ -255,11 +262,15 @@ module SearchHelper
opts[:data]['labels-endpoint'] = project_labels_path(@project)
opts[:data]['milestones-endpoint'] = project_milestones_path(@project)
opts[:data]['releases-endpoint'] = project_releases_path(@project)
+ opts[:data]['environments-endpoint'] =
+ unfoldered_environment_names_project_path(@project)
elsif @group.present?
opts[:data]['group-id'] = @group.id
opts[:data]['labels-endpoint'] = group_labels_path(@group)
opts[:data]['milestones-endpoint'] = group_milestones_path(@group)
opts[:data]['releases-endpoint'] = group_releases_path(@group)
+ opts[:data]['environments-endpoint'] =
+ unfoldered_environment_names_group_path(@group)
else
opts[:data]['labels-endpoint'] = dashboard_labels_path
opts[:data]['milestones-endpoint'] = dashboard_milestones_path
@@ -294,9 +305,25 @@ module SearchHelper
sanitize(html, tags: %w(a p ol ul li pre code))
end
- def show_user_search_tab?
- return false if Feature.disabled?(:users_search, default_enabled: true)
+ def simple_search_highlight_and_truncate(text, phrase, options = {})
+ text = Truncato.truncate(
+ text,
+ count_tags: false,
+ count_tail: false,
+ max_length: options.delete(:length) { 200 }
+ )
+
+ highlight(text, phrase.split, options)
+ end
+
+ # _search_highlight is used in EE override
+ def highlight_and_truncate_issue(issue, search_term, _search_highlight)
+ return unless issue.description.present?
+ simple_search_highlight_and_truncate(issue.description, search_term, highlighter: '<span class="gl-text-black-normal gl-font-weight-bold">\1</span>')
+ end
+
+ def show_user_search_tab?
if @project
project_search_tabs?(:members)
else
diff --git a/app/helpers/services_helper.rb b/app/helpers/services_helper.rb
index 6b5de73a831..114bbf59ae1 100644
--- a/app/helpers/services_helper.rb
+++ b/app/helpers/services_helper.rb
@@ -24,7 +24,7 @@ module ServicesHelper
when "commit", "commit_events"
s_("ProjectService|Event will be triggered when a commit is created/updated")
when "deployment"
- s_("ProjectService|Event will be triggered when a deployment finishes")
+ s_("ProjectService|Event will be triggered when a deployment starts or finishes")
when "alert"
s_("ProjectService|Event will be triggered when a new, unique alert is recorded")
end
@@ -124,6 +124,10 @@ module ServicesHelper
@group.present? && Feature.enabled?(:group_level_integrations, @group)
end
+ def instance_level_integrations?
+ !Gitlab.com?
+ end
+
extend self
private
diff --git a/app/helpers/snippets_helper.rb b/app/helpers/snippets_helper.rb
index 94c46feb8ae..1be7e240c1a 100644
--- a/app/helpers/snippets_helper.rb
+++ b/app/helpers/snippets_helper.rb
@@ -32,31 +32,6 @@ module SnippetsHelper
end
end
- # Get an array of line numbers surrounding a matching
- # line, bounded by min/max.
- #
- # @returns Array of line numbers
- def bounded_line_numbers(line, min, max, surrounding_lines)
- lower = line - surrounding_lines > min ? line - surrounding_lines : min
- upper = line + surrounding_lines < max ? line + surrounding_lines : max
- (lower..upper).to_a
- end
-
- def snippet_embed_tag(snippet)
- content_tag(:script, nil, src: gitlab_snippet_url(snippet, format: :js))
- end
-
- def snippet_embed_input(snippet)
- content_tag(:input,
- nil,
- type: :text,
- readonly: true,
- class: 'js-snippet-url-area snippet-embed-input form-control',
- data: { url: gitlab_snippet_url(snippet) },
- value: snippet_embed_tag(snippet),
- autocomplete: 'off')
- end
-
def snippet_badge(snippet)
return unless attrs = snippet_badge_attributes(snippet)
diff --git a/app/helpers/ssh_keys_helper.rb b/app/helpers/ssh_keys_helper.rb
new file mode 100644
index 00000000000..381db893943
--- /dev/null
+++ b/app/helpers/ssh_keys_helper.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+module SshKeysHelper
+ def ssh_key_delete_modal_data(key, path)
+ {
+ path: path,
+ method: 'delete',
+ qa_selector: 'delete_ssh_key_button',
+ modal_attributes: {
+ 'data-qa-selector': 'ssh_key_delete_modal',
+ title: _('Are you sure you want to delete this SSH key?'),
+ message: _('This action cannot be undone, and will permanently delete the %{key} SSH key') % { key: key.title },
+ okVariant: 'danger',
+ okTitle: _('Delete')
+ }
+ }
+ end
+end
diff --git a/app/helpers/startupjs_helper.rb b/app/helpers/startupjs_helper.rb
new file mode 100644
index 00000000000..b595590c7c9
--- /dev/null
+++ b/app/helpers/startupjs_helper.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module StartupjsHelper
+ def page_startup_graphql_calls
+ @graphql_startup_calls
+ end
+
+ def add_page_startup_graphql_call(query, variables = {})
+ @graphql_startup_calls ||= []
+ file_location = File.join(Rails.root, "app/graphql/queries/#{query}.query.graphql")
+
+ return unless File.exist?(file_location)
+
+ query_str = File.read(file_location)
+ @graphql_startup_calls << { query: query_str, variables: variables }
+ end
+end
diff --git a/app/helpers/suggest_pipeline_helper.rb b/app/helpers/suggest_pipeline_helper.rb
index aa67f0ea770..d64e8d6f2cd 100644
--- a/app/helpers/suggest_pipeline_helper.rb
+++ b/app/helpers/suggest_pipeline_helper.rb
@@ -2,7 +2,7 @@
module SuggestPipelineHelper
def should_suggest_gitlab_ci_yml?
- Feature.enabled?(:suggest_pipeline) &&
+ experiment_enabled?(:suggest_pipeline) &&
current_user &&
params[:suggest_gitlab_ci_yml] == 'true'
end
diff --git a/app/helpers/system_note_helper.rb b/app/helpers/system_note_helper.rb
index 0227ad1092d..79f4810e13a 100644
--- a/app/helpers/system_note_helper.rb
+++ b/app/helpers/system_note_helper.rb
@@ -2,6 +2,8 @@
module SystemNoteHelper
ICON_NAMES_BY_ACTION = {
+ 'approved' => 'approval',
+ 'unapproved' => 'unapproval',
'cherry_pick' => 'cherry-pick-commit',
'commit' => 'commit',
'description' => 'pencil-square',
@@ -11,6 +13,7 @@ module SystemNoteHelper
'closed' => 'issue-close',
'time_tracking' => 'timer',
'assignee' => 'user',
+ 'reviewer' => 'user',
'title' => 'pencil-square',
'task' => 'task-done',
'label' => 'label',
@@ -34,7 +37,8 @@ module SystemNoteHelper
'designs_discussion_added' => 'doc-image',
'status' => 'status',
'alert_issue_added' => 'issues',
- 'new_alert_added' => 'warning'
+ 'new_alert_added' => 'warning',
+ 'severity' => 'information-o'
}.freeze
def system_note_icon_name(note)
diff --git a/app/helpers/tags_helper.rb b/app/helpers/tags_helper.rb
index 4984b51555d..bfc8803f514 100644
--- a/app/helpers/tags_helper.rb
+++ b/app/helpers/tags_helper.rb
@@ -38,4 +38,13 @@ module TagsHelper
text.html_safe
end
+
+ def delete_tag_modal_attributes(tag_name)
+ {
+ title: s_('TagsPage|Delete tag'),
+ message: s_('TagsPage|Deleting the %{tag_name} tag cannot be undone. Are you sure?') % { tag_name: tag_name },
+ okVariant: 'danger',
+ okTitle: s_('TagsPage|Delete tag')
+ }.to_json
+ end
end
diff --git a/app/helpers/timeboxes_helper.rb b/app/helpers/timeboxes_helper.rb
index 34919f994ee..bbf8cf7dac3 100644
--- a/app/helpers/timeboxes_helper.rb
+++ b/app/helpers/timeboxes_helper.rb
@@ -228,8 +228,8 @@ module TimeboxesHelper
end
alias_method :milestone_date_range, :timebox_date_range
- def milestone_tab_path(milestone, tab)
- url_for(action: tab, format: :json)
+ def milestone_tab_path(milestone, tab, params = {})
+ url_for(params.merge(action: tab, format: :json))
end
def update_milestone_path(milestone, params = {})
diff --git a/app/helpers/todos_helper.rb b/app/helpers/todos_helper.rb
index 9865f7dfbef..7b0e0df8998 100644
--- a/app/helpers/todos_helper.rb
+++ b/app/helpers/todos_helper.rb
@@ -16,6 +16,7 @@ module TodosHelper
def todo_action_name(todo)
case todo.action
when Todo::ASSIGNED then todo.self_added? ? 'assigned' : 'assigned you'
+ when Todo::REVIEW_REQUESTED then 'requested a review of'
when Todo::MENTIONED then "mentioned #{todo_action_subject(todo)} on"
when Todo::BUILD_FAILED then 'The build failed for'
when Todo::MARKED then 'added a todo for'
@@ -26,6 +27,13 @@ module TodosHelper
end
end
+ def todo_self_addressing(todo)
+ case todo.action
+ when Todo::ASSIGNED then 'to yourself'
+ when Todo::REVIEW_REQUESTED then 'from yourself'
+ end
+ end
+
def todo_target_link(todo)
text = raw(todo_target_type_name(todo) + ' ') +
if todo.for_commit?
@@ -141,6 +149,7 @@ module TodosHelper
[
{ 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' },
diff --git a/app/helpers/tree_helper.rb b/app/helpers/tree_helper.rb
index 7644ed783eb..563450159b5 100644
--- a/app/helpers/tree_helper.rb
+++ b/app/helpers/tree_helper.rb
@@ -1,6 +1,9 @@
# frozen_string_literal: true
module TreeHelper
+ include BlobHelper
+ include WebIdeButtonHelper
+
FILE_LIMIT = 1_000
# Sorts a repository's tree so that folders are before files and renders
@@ -31,7 +34,7 @@ module TreeHelper
# mode - File unix mode
# name - File name
def tree_icon(type, mode, name)
- icon([file_type_icon_class(type, mode, name), 'fw'])
+ sprite_icon(file_type_icon_class(type, mode, name))
end
# Using Rails `*_path` methods can be slow, especially when generating
@@ -199,38 +202,26 @@ module TreeHelper
}
end
- def ide_base_path(project)
- can_push_code = current_user&.can?(:push_code, project)
- fork_path = current_user&.fork_of(project)&.full_path
+ def web_ide_button_data(options = {})
+ {
+ project_path: project_to_use.full_path,
+ ref: ActionDispatch::Journey::Router::Utils.escape_path(@ref),
- if can_push_code
- project.full_path
- else
- fork_path || project.full_path
- end
- end
+ is_fork: fork?,
+ needs_to_fork: needs_to_fork?,
+ gitpod_enabled: !current_user.nil? && current_user.gitpod_enabled,
+ is_blob: !options[:blob].nil?,
- def vue_ide_link_data(project, ref)
- can_collaborate = can_collaborate_with_project?(project)
- can_create_mr_from_fork = can?(current_user, :fork_project, project) && can?(current_user, :create_merge_request_in, project)
- show_web_ide_button = (can_collaborate || current_user&.already_forked?(project) || can_create_mr_from_fork)
+ show_edit_button: show_edit_button?,
+ show_web_ide_button: show_web_ide_button?,
+ show_gitpod_button: show_gitpod_button?,
- {
- ide_base_path: ide_base_path(project),
- needs_to_fork: !can_collaborate && !current_user&.already_forked?(project),
- show_web_ide_button: show_web_ide_button,
- show_gitpod_button: show_web_ide_button && Gitlab::Gitpod.feature_and_settings_enabled?(project),
- gitpod_url: full_gitpod_url(project, ref),
- gitpod_enabled: current_user&.gitpod_enabled
+ web_ide_url: web_ide_url,
+ edit_url: edit_url,
+ gitpod_url: gitpod_url
}
end
- def full_gitpod_url(project, ref)
- return "" unless Gitlab::Gitpod.feature_and_settings_enabled?(project)
-
- "#{Gitlab::CurrentSettings.gitpod_url}##{project_tree_url(project, tree_join(ref, @path || ''))}"
- end
-
def directory_download_links(project, ref, archive_prefix)
Gitlab::Workhorse::ARCHIVE_FORMATS.map do |fmt|
{
diff --git a/app/helpers/user_callouts_helper.rb b/app/helpers/user_callouts_helper.rb
index 967271a8431..0cdf53d6174 100644
--- a/app/helpers/user_callouts_helper.rb
+++ b/app/helpers/user_callouts_helper.rb
@@ -9,7 +9,7 @@ module UserCalloutsHelper
TABS_POSITION_HIGHLIGHT = 'tabs_position_highlight'
WEBHOOKS_MOVED = 'webhooks_moved'
CUSTOMIZE_HOMEPAGE = 'customize_homepage'
- WEB_IDE_ALERT_DISMISSED = 'web_ide_alert_dismissed'
+ FEATURE_FLAGS_NEW_VERSION = 'feature_flags_new_version'
def show_admin_integrations_moved?
!user_dismissed?(ADMIN_INTEGRATIONS_MOVED)
@@ -51,8 +51,8 @@ module UserCalloutsHelper
customize_homepage && !user_dismissed?(CUSTOMIZE_HOMEPAGE)
end
- def show_web_ide_alert?
- !user_dismissed?(WEB_IDE_ALERT_DISMISSED)
+ def show_feature_flags_new_version?
+ !user_dismissed?(FEATURE_FLAGS_NEW_VERSION)
end
private
diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb
index c1bca6b4c41..f47937e6d57 100644
--- a/app/helpers/users_helper.rb
+++ b/app/helpers/users_helper.rb
@@ -84,7 +84,7 @@ module UsersHelper
def user_badges_in_admin_section(user)
[].tap do |badges|
- badges << { text: s_('AdminUsers|Blocked'), variant: 'danger' } if user.blocked?
+ badges << blocked_user_badge(user) if user.blocked?
badges << { text: s_('AdminUsers|Admin'), variant: 'success' } if user.admin?
badges << { text: s_('AdminUsers|External'), variant: 'secondary' } if user.external?
badges << { text: s_("AdminUsers|It's you!"), variant: nil } if current_user == user
@@ -106,8 +106,19 @@ module UsersHelper
end
end
+ def can_force_email_confirmation?(user)
+ !user.confirmed?
+ end
+
private
+ def blocked_user_badge(user)
+ pending_approval_badge = { text: s_('AdminUsers|Pending approval'), variant: 'info' }
+ return pending_approval_badge if user.blocked_pending_approval?
+
+ { text: s_('AdminUsers|Blocked'), variant: 'danger' }
+ end
+
def get_profile_tabs
tabs = []
diff --git a/app/helpers/visibility_level_helper.rb b/app/helpers/visibility_level_helper.rb
index 304b58d232a..a7b9e17c898 100644
--- a/app/helpers/visibility_level_helper.rb
+++ b/app/helpers/visibility_level_helper.rb
@@ -23,8 +23,6 @@ module VisibilityLevelHelper
project_visibility_level_description(level)
when Group
group_visibility_level_description(level)
- when Snippet
- snippet_visibility_level_description(level, form_model)
end
end
@@ -50,21 +48,6 @@ module VisibilityLevelHelper
end
end
- def snippet_visibility_level_description(level, snippet = nil)
- case level
- when Gitlab::VisibilityLevel::PRIVATE
- if snippet.is_a? ProjectSnippet
- _("The snippet is visible only to project members.")
- else
- _("The snippet is visible only to me.")
- end
- when Gitlab::VisibilityLevel::INTERNAL
- _("The snippet is visible to any logged in user.")
- when Gitlab::VisibilityLevel::PUBLIC
- _("The snippet can be accessed without any authentication.")
- end
- end
-
# Note: these messages closely mirror the form validation strings found in the project
# model and any changes or additons to these may also need to be made there.
def disallowed_project_visibility_level_description(level, project)
diff --git a/app/helpers/web_ide_button_helper.rb b/app/helpers/web_ide_button_helper.rb
new file mode 100644
index 00000000000..0a4d47eed52
--- /dev/null
+++ b/app/helpers/web_ide_button_helper.rb
@@ -0,0 +1,61 @@
+# frozen_string_literal: true
+
+module WebIdeButtonHelper
+ def project_fork
+ current_user&.fork_of(@project)
+ end
+
+ def project_to_use
+ fork? ? project_fork : @project
+ end
+
+ def can_collaborate?
+ can_collaborate_with_project?(@project)
+ end
+
+ def can_create_mr_from_fork?
+ can?(current_user, :fork_project, @project) && can?(current_user, :create_merge_request_in, @project)
+ end
+
+ def show_web_ide_button?
+ can_collaborate? || can_create_mr_from_fork?
+ end
+
+ def show_edit_button?
+ readable_blob? && show_web_ide_button?
+ end
+
+ def show_gitpod_button?
+ show_web_ide_button? && Gitlab::Gitpod.feature_and_settings_enabled?(@project)
+ end
+
+ def can_push_code?
+ current_user&.can?(:push_code, @project)
+ end
+
+ def fork?
+ !project_fork.nil? && !can_push_code?
+ end
+
+ def readable_blob?
+ !readable_blob({}, @path, @project, @ref).nil?
+ end
+
+ def needs_to_fork?
+ !can_collaborate? && !current_user&.already_forked?(@project)
+ end
+
+ def web_ide_url
+ ide_edit_path(project_to_use, @ref, @path || '')
+ end
+
+ def edit_url
+ readable_blob? ? edit_blob_path(@project, @ref, @path || '') : ''
+ end
+
+ def gitpod_url
+ return "" unless Gitlab::Gitpod.feature_and_settings_enabled?(@project)
+
+ "#{Gitlab::CurrentSettings.gitpod_url}##{project_tree_url(@project, tree_join(@ref, @path || ''))}"
+ end
+end
diff --git a/app/helpers/webpack_helper.rb b/app/helpers/webpack_helper.rb
index 345ddcf023a..170e3c45a21 100644
--- a/app/helpers/webpack_helper.rb
+++ b/app/helpers/webpack_helper.rb
@@ -57,10 +57,12 @@ module WebpackHelper
end
def webpack_public_host
- if Rails.env.test? && Rails.configuration.webpack.dev_server.enabled
- host = Rails.configuration.webpack.dev_server.host
- port = Rails.configuration.webpack.dev_server.port
- protocol = Rails.configuration.webpack.dev_server.https ? 'https' : 'http'
+ # We do not proxy the webpack output in the 'test' environment,
+ # so we must reference the webpack dev server directly.
+ if Rails.env.test? && Gitlab.config.webpack.dev_server.enabled
+ host = Gitlab.config.webpack.dev_server.host
+ port = Gitlab.config.webpack.dev_server.port
+ protocol = Gitlab.config.webpack.dev_server.https ? 'https' : 'http'
"#{protocol}://#{host}:#{port}"
else
ActionController::Base.asset_host.try(:chomp, '/')
@@ -68,8 +70,8 @@ module WebpackHelper
end
def webpack_public_path
- relative_path = Rails.application.config.relative_url_root
- webpack_path = Rails.application.config.webpack.public_path
+ relative_path = Gitlab.config.gitlab.relative_url_root
+ webpack_path = Gitlab.config.webpack.public_path
File.join(webpack_public_host.to_s, relative_path.to_s, webpack_path.to_s, '')
end
end
diff --git a/app/helpers/whats_new_helper.rb b/app/helpers/whats_new_helper.rb
index f0044daa645..c183ed7f12a 100644
--- a/app/helpers/whats_new_helper.rb
+++ b/app/helpers/whats_new_helper.rb
@@ -1,24 +1,27 @@
# frozen_string_literal: true
module WhatsNewHelper
- EMPTY_JSON = ''.to_json
+ include Gitlab::WhatsNew
- def whats_new_most_recent_release_items
- YAML.load_file(most_recent_release_file_path).to_json
+ def whats_new_most_recent_release_items_count
+ Gitlab::ProcessMemoryCache.cache_backend.fetch('whats_new:release_items_count', expires_in: CACHE_DURATION) do
+ whats_new_most_recent_release_items&.count
+ end
+ end
- rescue => e
- Gitlab::ErrorTracking.track_exception(e, yaml_file_path: most_recent_release_file_path)
+ def whats_new_storage_key
+ return unless whats_new_most_recent_version
- EMPTY_JSON
+ ['display-whats-new-notification', whats_new_most_recent_version].join('-')
end
private
- def most_recent_release_file_path
- Dir.glob(files_path).max
- end
-
- def files_path
- Rails.root.join('data', 'whats_new', '*.yml')
+ def whats_new_most_recent_version
+ Gitlab::ProcessMemoryCache.cache_backend.fetch('whats_new:release_version', expires_in: CACHE_DURATION) do
+ if whats_new_most_recent_release_items
+ whats_new_most_recent_release_items.first.try(:[], 'release')
+ end
+ end
end
end
diff --git a/app/helpers/wiki_helper.rb b/app/helpers/wiki_helper.rb
index 8c756b9370b..786081ca815 100644
--- a/app/helpers/wiki_helper.rb
+++ b/app/helpers/wiki_helper.rb
@@ -142,7 +142,8 @@ module WikiHelper
'wiki-format' => page.format,
'wiki-title-size' => page.title.bytesize,
'wiki-content-size' => page.raw_content.bytesize,
- 'wiki-directory-nest-level' => page.path.scan('/').count
+ 'wiki-directory-nest-level' => page.path.scan('/').count,
+ 'wiki-container-type' => page.wiki.container.class.name
}
end