summaryrefslogtreecommitdiff
path: root/app/helpers
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-09-19 01:45:44 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-09-19 01:45:44 +0000
commit85dc423f7090da0a52c73eb66faf22ddb20efff9 (patch)
tree9160f299afd8c80c038f08e1545be119f5e3f1e1 /app/helpers
parent15c2c8c66dbe422588e5411eee7e68f1fa440bb8 (diff)
downloadgitlab-ce-85dc423f7090da0a52c73eb66faf22ddb20efff9.tar.gz
Add latest changes from gitlab-org/gitlab@13-4-stable-ee
Diffstat (limited to 'app/helpers')
-rw-r--r--app/helpers/application_helper.rb8
-rw-r--r--app/helpers/application_settings_helper.rb7
-rw-r--r--app/helpers/auth_helper.rb4
-rw-r--r--app/helpers/blob_helper.rb7
-rw-r--r--app/helpers/boards_helper.rb4
-rw-r--r--app/helpers/ci/jobs_helper.rb1
-rw-r--r--app/helpers/ci/pipelines_helper.rb33
-rw-r--r--app/helpers/clusters_helper.rb6
-rw-r--r--app/helpers/container_registry_helper.rb8
-rw-r--r--app/helpers/dashboard_helper.rb4
-rw-r--r--app/helpers/deploy_tokens_helper.rb9
-rw-r--r--app/helpers/dev_ops_report_helper.rb (renamed from app/helpers/dev_ops_score_helper.rb)2
-rw-r--r--app/helpers/diff_helper.rb37
-rw-r--r--app/helpers/dropdowns_helper.rb44
-rw-r--r--app/helpers/emails_helper.rb45
-rw-r--r--app/helpers/environments_helper.rb78
-rw-r--r--app/helpers/form_helper.rb23
-rw-r--r--app/helpers/groups/group_members_helper.rb79
-rw-r--r--app/helpers/groups_helper.rb15
-rw-r--r--app/helpers/icons_helper.rb2
-rw-r--r--app/helpers/issuables_helper.rb15
-rw-r--r--app/helpers/issues_helper.rb2
-rw-r--r--app/helpers/lazy_image_tag_helper.rb2
-rw-r--r--app/helpers/nav_helper.rb6
-rw-r--r--app/helpers/notes_helper.rb6
-rw-r--r--app/helpers/notifications_helper.rb10
-rw-r--r--app/helpers/operations_helper.rb1
-rw-r--r--app/helpers/preferences_helper.rb11
-rw-r--r--app/helpers/projects_helper.rb6
-rw-r--r--app/helpers/releases_helper.rb1
-rw-r--r--app/helpers/search_helper.rb41
-rw-r--r--app/helpers/services_helper.rb28
-rw-r--r--app/helpers/snippets_helper.rb2
-rw-r--r--app/helpers/startup_css_helper.rb7
-rw-r--r--app/helpers/submodule_helper.rb54
-rw-r--r--app/helpers/system_note_helper.rb5
-rw-r--r--app/helpers/tab_helper.rb2
-rw-r--r--app/helpers/tree_helper.rb34
-rw-r--r--app/helpers/user_callouts_helper.rb10
-rw-r--r--app/helpers/whats_new_helper.rb24
-rw-r--r--app/helpers/wiki_helper.rb9
41 files changed, 551 insertions, 141 deletions
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 41b20a1d9a0..a81225c8954 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -4,6 +4,8 @@ require 'digest/md5'
require 'uri'
module ApplicationHelper
+ include StartupCssHelper
+
# See https://docs.gitlab.com/ee/development/ee_features.html#code-in-app-views
# rubocop: disable CodeReuse/ActiveRecord
def render_if_exists(partial, locals = {})
@@ -235,13 +237,9 @@ module ApplicationHelper
"#{request.path}?#{options.compact.to_param}"
end
- def use_startup_css?
- Feature.enabled?(:startup_css) && !Rails.env.test?
- end
-
def stylesheet_link_tag_defer(path)
if use_startup_css?
- stylesheet_link_tag(path, media: "print")
+ stylesheet_link_tag(path, media: "print", crossorigin: ActionController::Base.asset_host ? 'anonymous' : nil)
else
stylesheet_link_tag(path, media: "all")
end
diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb
index 404700bb25e..9245cc1cb1c 100644
--- a/app/helpers/application_settings_helper.rb
+++ b/app/helpers/application_settings_helper.rb
@@ -222,6 +222,8 @@ module ApplicationSettingsHelper
:gitaly_timeout_default,
:gitaly_timeout_medium,
:gitaly_timeout_fast,
+ :gitpod_enabled,
+ :gitpod_url,
:grafana_enabled,
:grafana_url,
:gravatar_enabled,
@@ -298,7 +300,6 @@ module ApplicationSettingsHelper
:unique_ips_limit_per_user,
:unique_ips_limit_time_window,
:usage_ping_enabled,
- :instance_statistics_visibility_private,
:user_default_external,
:user_show_add_ssh_key_message,
:user_default_internal_regex,
@@ -313,7 +314,6 @@ module ApplicationSettingsHelper
:snowplow_cookie_domain,
:snowplow_enabled,
:snowplow_app_id,
- :snowplow_iglu_registry_url,
:push_event_hooks_limit,
:push_event_activities_limit,
:custom_http_clone_url_root,
@@ -328,7 +328,8 @@ module ApplicationSettingsHelper
:group_import_limit,
:group_export_limit,
:group_download_export_limit,
- :wiki_page_max_content_bytes
+ :wiki_page_max_content_bytes,
+ :container_registry_delete_tags_service_timeout
]
end
diff --git a/app/helpers/auth_helper.rb b/app/helpers/auth_helper.rb
index a57e27d23c8..7f8cb66a84f 100644
--- a/app/helpers/auth_helper.rb
+++ b/app/helpers/auth_helper.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module AuthHelper
- PROVIDERS_WITH_ICONS = %w(twitter github gitlab bitbucket google_oauth2 facebook azure_oauth2 authentiq salesforce).freeze
+ PROVIDERS_WITH_ICONS = %w(twitter github gitlab bitbucket google_oauth2 facebook azure_oauth2 authentiq salesforce atlassian_oauth2).freeze
LDAP_PROVIDER = /\Aldap/.freeze
def ldap_enabled?
@@ -133,6 +133,8 @@ module AuthHelper
# rubocop: disable CodeReuse/ActiveRecord
def auth_active?(provider)
+ return current_user.atlassian_identity.present? if provider == :atlassian_oauth2
+
current_user.identities.exists?(provider: provider.to_s)
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb
index 615c834c529..2eff87ae0ec 100644
--- a/app/helpers/blob_helper.rb
+++ b/app/helpers/blob_helper.rb
@@ -41,7 +41,7 @@ module BlobHelper
end
def encode_ide_path(path)
- url_encode(path).gsub('%2F', '/')
+ ERB::Util.url_encode(path).gsub('%2F', '/')
end
def edit_blob_button(project = @project, ref = @ref, path = @path, options = {})
@@ -375,4 +375,9 @@ module BlobHelper
def human_access
@project.team.human_max_access(current_user&.id).try(:downcase)
end
+
+ def editing_ci_config?
+ @path.to_s.end_with?(Ci::Pipeline::CONFIG_EXTENSION) ||
+ @path.to_s == @project.ci_config_path_or_default
+ end
end
diff --git a/app/helpers/boards_helper.rb b/app/helpers/boards_helper.rb
index f8c00f3a4cd..6a4a7a8dfb2 100644
--- a/app/helpers/boards_helper.rb
+++ b/app/helpers/boards_helper.rb
@@ -11,13 +11,13 @@ module BoardsHelper
lists_endpoint: board_lists_path(board),
board_id: board.id,
disabled: (!can?(current_user, :create_non_backlog_issues, board)).to_s,
- issue_link_base: build_issue_link_base,
root_path: root_path,
full_path: full_path,
bulk_update_path: @bulk_issues_path,
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
+ parent: current_board_parent.model_name.param_key,
+ group_id: @group&.id
}
end
diff --git a/app/helpers/ci/jobs_helper.rb b/app/helpers/ci/jobs_helper.rb
index 0344413b849..e876eb64029 100644
--- a/app/helpers/ci/jobs_helper.rb
+++ b/app/helpers/ci/jobs_helper.rb
@@ -6,6 +6,7 @@ module Ci
{
"endpoint" => project_job_path(@project, @build, format: :json),
"project_path" => @project.full_path,
+ "artifact_help_url" => help_page_path('user/gitlab_com/index.html', anchor: 'gitlab-cicd'),
"deployment_help_url" => help_page_path('user/project/clusters/index.html', anchor: 'troubleshooting'),
"runner_help_url" => help_page_path('ci/runners/README.html', anchor: 'set-maximum-job-timeout-for-a-runner'),
"runner_settings_url" => project_runners_path(@build.project, anchor: 'js-runners-settings'),
diff --git a/app/helpers/ci/pipelines_helper.rb b/app/helpers/ci/pipelines_helper.rb
index 749726e0e33..309aa477108 100644
--- a/app/helpers/ci/pipelines_helper.rb
+++ b/app/helpers/ci/pipelines_helper.rb
@@ -2,16 +2,35 @@
module Ci
module PipelinesHelper
+ include Gitlab::Ci::Warnings
+
def pipeline_warnings(pipeline)
return unless pipeline.warning_messages.any?
- content_tag(:div, class: 'alert alert-warning') do
- content_tag(:h4, 'Warning:') <<
- content_tag(:div) do
- pipeline.warning_messages.each do |warning|
- concat(markdown(warning.content))
- end
- end
+ total_warnings = pipeline.warning_messages.length
+ message = warning_header(total_warnings)
+
+ content_tag(:div, class: 'bs-callout bs-callout-warning') do
+ content_tag(:details) do
+ concat content_tag(:summary, message, class: 'gl-mb-2')
+ warning_markdown(pipeline) { |markdown| concat markdown }
+ end
+ end
+ end
+
+ def warning_header(count)
+ message = _("%{total_warnings} warning(s) found:") % { total_warnings: count }
+
+ return message unless count > MAX_LIMIT
+
+ _("%{message} showing first %{warnings_displayed}") % { message: message, warnings_displayed: MAX_LIMIT }
+ end
+
+ private
+
+ def warning_markdown(pipeline)
+ pipeline.warning_messages(limit: MAX_LIMIT).each do |warning|
+ yield markdown(warning.content)
end
end
end
diff --git a/app/helpers/clusters_helper.rb b/app/helpers/clusters_helper.rb
index b97e847c397..caad215e996 100644
--- a/app/helpers/clusters_helper.rb
+++ b/app/helpers/clusters_helper.rb
@@ -36,6 +36,12 @@ module ClustersHelper
}
end
+ def js_cluster_new
+ {
+ cluster_connect_help_path: help_page_path('user/project/clusters/add_remove_clusters', anchor: 'add-existing-cluster')
+ }
+ 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) ||
diff --git a/app/helpers/container_registry_helper.rb b/app/helpers/container_registry_helper.rb
new file mode 100644
index 00000000000..9a5d84a90dd
--- /dev/null
+++ b/app/helpers/container_registry_helper.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+module ContainerRegistryHelper
+ def limit_delete_tags_service?
+ Feature.enabled?(:container_registry_expiration_policies_throttling) &&
+ ContainerRegistry::Client.supports_tag_delete?
+ end
+end
diff --git a/app/helpers/dashboard_helper.rb b/app/helpers/dashboard_helper.rb
index 0ba03cd90ea..195b3162039 100644
--- a/app/helpers/dashboard_helper.rb
+++ b/app/helpers/dashboard_helper.rb
@@ -58,10 +58,6 @@ module DashboardHelper
links += [:activity, :milestones]
end
- if can?(current_user, :read_instance_statistics)
- links << :analytics
- end
-
links
end
end
diff --git a/app/helpers/deploy_tokens_helper.rb b/app/helpers/deploy_tokens_helper.rb
index 80a5bb44c69..d6fbe0b6b45 100644
--- a/app/helpers/deploy_tokens_helper.rb
+++ b/app/helpers/deploy_tokens_helper.rb
@@ -7,8 +7,13 @@ module DeployTokensHelper
Rails.env.test?
end
- def container_registry_enabled?(project)
+ def container_registry_enabled?(group_or_project)
Gitlab.config.registry.enabled &&
- can?(current_user, :read_container_image, project)
+ can?(current_user, :read_container_image, group_or_project)
+ end
+
+ def packages_registry_enabled?(group_or_project)
+ Gitlab.config.packages.enabled &&
+ can?(current_user, :read_package, group_or_project)
end
end
diff --git a/app/helpers/dev_ops_score_helper.rb b/app/helpers/dev_ops_report_helper.rb
index 9a673998149..ab7e56fc1a2 100644
--- a/app/helpers/dev_ops_score_helper.rb
+++ b/app/helpers/dev_ops_report_helper.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-module DevOpsScoreHelper
+module DevOpsReportHelper
def score_level(score)
if score < 33.33
'low'
diff --git a/app/helpers/diff_helper.rb b/app/helpers/diff_helper.rb
index 3b25de521d0..7c254e069f6 100644
--- a/app/helpers/diff_helper.rb
+++ b/app/helpers/diff_helper.rb
@@ -100,20 +100,43 @@ module DiffHelper
end
def submodule_link(blob, ref, repository = @repository)
- project_url, tree_url = submodule_links(blob, ref, repository)
- commit_id = if tree_url.nil?
- Commit.truncate_sha(blob.id)
- else
- link_to Commit.truncate_sha(blob.id), tree_url
- end
+ urls = submodule_links(blob, ref, repository)
+
+ folder_name = truncate(blob.name, length: 40)
+ folder_name = link_to(folder_name, urls.web) if urls&.web
+
+ commit_id = Commit.truncate_sha(blob.id)
+ commit_id = link_to(commit_id, urls.tree) if urls&.tree
[
- content_tag(:span, link_to(truncate(blob.name, length: 40), project_url)),
+ content_tag(:span, folder_name),
'@',
content_tag(:span, commit_id, class: 'commit-sha')
].join(' ').html_safe
end
+ def submodule_diff_compare_link(diff_file)
+ compare_url = submodule_links(diff_file.blob, diff_file.content_sha, diff_file.repository, diff_file)&.compare
+
+ link = ""
+
+ if compare_url
+
+ link_text = [
+ _('Compare'),
+ ' ',
+ content_tag(:span, Commit.truncate_sha(diff_file.old_blob.id), class: 'commit-sha'),
+ '...',
+ content_tag(:span, Commit.truncate_sha(diff_file.blob.id), class: 'commit-sha')
+ ].join('').html_safe
+
+ tooltip = _('Compare submodule commit revisions')
+ link = content_tag(:span, link_to(link_text, compare_url, class: 'btn has-tooltip', title: tooltip), class: 'submodule-compare')
+ end
+
+ link
+ end
+
def diff_file_blob_raw_url(diff_file, only_path: false)
project_raw_url(@project, tree_join(diff_file.content_sha, diff_file.file_path), only_path: only_path)
end
diff --git a/app/helpers/dropdowns_helper.rb b/app/helpers/dropdowns_helper.rb
index 772a5f79a4d..84aa08281f6 100644
--- a/app/helpers/dropdowns_helper.rb
+++ b/app/helpers/dropdowns_helper.rb
@@ -62,20 +62,37 @@ module DropdownsHelper
end
def dropdown_title(title, options: {})
- content_tag :div, class: "dropdown-title" do
+ has_back = options.fetch(:back, false)
+ has_close = options.fetch(:close, true)
+
+ container_class = %w[dropdown-title gl-display-flex]
+ margin_class = []
+
+ if has_back && has_close
+ container_class << 'gl-justify-content-space-between'
+ elsif has_back
+ margin_class << 'gl-mr-auto'
+ elsif has_close
+ margin_class << 'gl-ml-auto'
+ end
+
+ container_class = container_class.join(' ')
+ margin_class = margin_class.join(' ')
+
+ content_tag :div, class: container_class do
title_output = []
- if options.fetch(:back, false)
- title_output << content_tag(:button, class: "dropdown-title-button dropdown-menu-back", aria: { label: "Go back" }, type: "button") do
- icon('arrow-left')
+ if has_back
+ title_output << content_tag(:button, class: "dropdown-title-button dropdown-menu-back " + margin_class, aria: { label: "Go back" }, type: "button") do
+ sprite_icon('arrow-left')
end
end
- title_output << content_tag(:span, title)
+ title_output << content_tag(:span, title, class: margin_class)
- if options.fetch(:close, true)
- title_output << content_tag(:button, class: "dropdown-title-button dropdown-menu-close", aria: { label: "Close" }, type: "button") do
- icon('times', class: 'dropdown-menu-close-icon')
+ if has_close
+ title_output << content_tag(:button, class: "dropdown-title-button dropdown-menu-close " + margin_class, aria: { label: "Close" }, type: "button") do
+ sprite_icon('close', size: 16, css_class: 'dropdown-menu-close-icon')
end
end
@@ -83,20 +100,11 @@ module DropdownsHelper
end
end
- def dropdown_input(placeholder, input_id: nil)
- content_tag :div, class: "dropdown-input" do
- filter_output = text_field_tag input_id, nil, class: "dropdown-input-field dropdown-no-filter", placeholder: placeholder, autocomplete: 'off'
- filter_output << icon('times', class: "dropdown-input-clear js-dropdown-input-clear", role: "button")
-
- filter_output.html_safe
- end
- end
-
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 << icon('times', class: "dropdown-input-clear js-dropdown-input-clear", role: "button")
+ filter_output << sprite_icon('close', size: 16, css_class: 'dropdown-input-clear js-dropdown-input-clear')
filter_output.html_safe
end
diff --git a/app/helpers/emails_helper.rb b/app/helpers/emails_helper.rb
index ba2330dfc9a..d5c22927991 100644
--- a/app/helpers/emails_helper.rb
+++ b/app/helpers/emails_helper.rb
@@ -177,8 +177,53 @@ module EmailsHelper
strip_tags(render_message(:footer_message, style: ''))
end
+ def say_hi(user)
+ _('Hi %{username}!') % { username: sanitize_name(user.name) }
+ end
+
+ def say_hello(user)
+ _('Hello, %{username}!') % { username: sanitize_name(user.name) }
+ end
+
+ def two_factor_authentication_disabled_text
+ _('Two-factor authentication has been disabled for your GitLab account.')
+ end
+
+ def re_enable_two_factor_authentication_text(format: nil)
+ url = profile_two_factor_auth_url
+
+ case format
+ when :html
+ settings_link_to = generate_link(_('two-factor authentication settings'), url).html_safe
+ _("If you want to re-enable two-factor authentication, visit the %{settings_link_to} page.").html_safe % { settings_link_to: settings_link_to }
+ else
+ _('If you want to re-enable two-factor authentication, visit %{two_factor_link}') %
+ { two_factor_link: url }
+ end
+ end
+
+ def admin_changed_password_text(format: nil)
+ url = Gitlab.config.gitlab.url
+
+ case format
+ when :html
+ link_to = generate_link(url, url).html_safe
+ _('An administrator changed the password for your GitLab account on %{link_to}.').html_safe % { link_to: link_to }
+ else
+ _('An administrator changed the password for your GitLab account on %{link_to}.') % { link_to: url }
+ end
+ end
+
+ def contact_your_administrator_text
+ _('Please contact your administrator with any questions.')
+ end
+
private
+ def generate_link(text, url)
+ link_to(text, url, target: :_blank, rel: 'noopener noreferrer')
+ end
+
def show_footer?
email_header_and_footer_enabled? && current_appearance&.show_footer?
end
diff --git a/app/helpers/environments_helper.rb b/app/helpers/environments_helper.rb
index 39be8ae9f60..7f0c59f65a0 100644
--- a/app/helpers/environments_helper.rb
+++ b/app/helpers/environments_helper.rb
@@ -12,8 +12,8 @@ module EnvironmentsHelper
def environments_folder_list_view_data
{
"endpoint" => folder_project_environments_path(@project, @folder, format: :json),
- "folder-name" => @folder,
- "can-read-environment" => can?(current_user, :read_environment, @project).to_s
+ "folder_name" => @folder,
+ "can_read_environment" => can?(current_user, :read_environment, @project).to_s
}
end
@@ -33,11 +33,11 @@ module EnvironmentsHelper
def environment_logs_data(project, environment)
{
- "environment-name": environment.name,
- "environments-path": project_environments_path(project, format: :json),
- "environment-id": environment.id,
- "cluster-applications-documentation-path" => help_page_path('user/clusters/applications.md', anchor: 'elastic-stack'),
- "clusters-path": project_clusters_path(project, format: :json)
+ "environment_name": environment.name,
+ "environments_path": project_environments_path(project, format: :json),
+ "environment_id": environment.id,
+ "cluster_applications_documentation_path" => help_page_path('user/clusters/applications.md', anchor: 'elastic-stack'),
+ "clusters_path": project_clusters_path(project, format: :json)
}
end
@@ -51,18 +51,18 @@ module EnvironmentsHelper
return {} unless project
{
- 'settings-path' => edit_project_service_path(project, 'prometheus'),
- 'clusters-path' => project_clusters_path(project),
- 'dashboards-endpoint' => project_performance_monitoring_dashboards_path(project, format: :json),
- 'default-branch' => project.default_branch,
- 'project-path' => project_path(project),
- 'tags-path' => project_tags_path(project),
- 'external-dashboard-url' => project.metrics_setting_external_dashboard_url,
- 'custom-metrics-path' => project_prometheus_metrics_path(project),
- 'validate-query-path' => validate_query_project_prometheus_metrics_path(project),
- 'custom-metrics-available' => "#{custom_metrics_available?(project)}",
- 'prometheus-alerts-available' => "#{can?(current_user, :read_prometheus_alerts, project)}",
- 'dashboard-timezone' => project.metrics_setting_dashboard_timezone.to_s.upcase
+ 'settings_path' => edit_project_service_path(project, 'prometheus'),
+ 'clusters_path' => project_clusters_path(project),
+ 'dashboards_endpoint' => project_performance_monitoring_dashboards_path(project, format: :json),
+ 'default_branch' => project.default_branch,
+ 'project_path' => project_path(project),
+ 'tags_path' => project_tags_path(project),
+ 'external_dashboard_url' => project.metrics_setting_external_dashboard_url,
+ 'custom_metrics_path' => project_prometheus_metrics_path(project),
+ 'validate_query_path' => validate_query_project_prometheus_metrics_path(project),
+ 'custom_metrics_available' => "#{custom_metrics_available?(project)}",
+ 'prometheus_alerts_available' => "#{can?(current_user, :read_prometheus_alerts, project)}",
+ 'dashboard_timezone' => project.metrics_setting_dashboard_timezone.to_s.upcase
}
end
@@ -70,11 +70,11 @@ module EnvironmentsHelper
return {} unless environment
{
- 'metrics-dashboard-base-path' => metrics_dashboard_base_path(environment, project),
- 'current-environment-name' => environment.name,
- 'has-metrics' => "#{environment.has_metrics?}",
- 'prometheus-status' => "#{environment.prometheus_status}",
- 'environment-state' => "#{environment.state}"
+ 'metrics_dashboard_base_path' => metrics_dashboard_base_path(environment, project),
+ 'current_environment_name' => environment.name,
+ 'has_metrics' => "#{environment.has_metrics?}",
+ 'prometheus_status' => "#{environment.prometheus_status}",
+ 'environment_state' => "#{environment.state}"
}
end
@@ -93,26 +93,26 @@ module EnvironmentsHelper
return {} unless project && environment
{
- 'metrics-endpoint' => additional_metrics_project_environment_path(project, environment, format: :json),
- 'dashboard-endpoint' => metrics_dashboard_project_environment_path(project, environment, format: :json),
- 'deployments-endpoint' => project_environment_deployments_path(project, environment, format: :json),
- 'alerts-endpoint' => project_prometheus_alerts_path(project, environment_id: environment.id, format: :json),
- 'operations-settings-path' => project_settings_operations_path(project),
- 'can-access-operations-settings' => can?(current_user, :admin_operations, project).to_s,
- 'panel-preview-endpoint' => project_metrics_dashboards_builder_path(project, format: :json)
+ 'metrics_endpoint' => additional_metrics_project_environment_path(project, environment, format: :json),
+ 'dashboard_endpoint' => metrics_dashboard_project_environment_path(project, environment, format: :json),
+ 'deployments_endpoint' => project_environment_deployments_path(project, environment, format: :json),
+ 'alerts_endpoint' => project_prometheus_alerts_path(project, environment_id: environment.id, format: :json),
+ 'operations_settings_path' => project_settings_operations_path(project),
+ 'can_access_operations_settings' => can?(current_user, :admin_operations, project).to_s,
+ 'panel_preview_endpoint' => project_metrics_dashboards_builder_path(project, format: :json)
}
end
def static_metrics_data
{
- 'documentation-path' => help_page_path('administration/monitoring/prometheus/index.md'),
- 'add-dashboard-documentation-path' => help_page_path('operations/metrics/dashboards/index.md', anchor: 'add-a-new-dashboard-to-your-project'),
- 'empty-getting-started-svg-path' => image_path('illustrations/monitoring/getting_started.svg'),
- 'empty-loading-svg-path' => image_path('illustrations/monitoring/loading.svg'),
- 'empty-no-data-svg-path' => image_path('illustrations/monitoring/no_data.svg'),
- 'empty-no-data-small-svg-path' => image_path('illustrations/chart-empty-state-small.svg'),
- 'empty-unable-to-connect-svg-path' => image_path('illustrations/monitoring/unable_to_connect.svg'),
- 'custom-dashboard-base-path' => Gitlab::Metrics::Dashboard::RepoDashboardFinder::DASHBOARD_ROOT
+ 'documentation_path' => help_page_path('administration/monitoring/prometheus/index.md'),
+ 'add_dashboard_documentation_path' => help_page_path('operations/metrics/dashboards/index.md', anchor: 'add-a-new-dashboard-to-your-project'),
+ 'empty_getting_started_svg_path' => image_path('illustrations/monitoring/getting_started.svg'),
+ 'empty_loading_svg_path' => image_path('illustrations/monitoring/loading.svg'),
+ 'empty_no_data_svg_path' => image_path('illustrations/monitoring/no_data.svg'),
+ 'empty_no_data_small_svg_path' => image_path('illustrations/chart-empty-state-small.svg'),
+ 'empty_unable_to_connect_svg_path' => image_path('illustrations/monitoring/unable_to_connect.svg'),
+ 'custom_dashboard_base_path' => Gitlab::Metrics::Dashboard::RepoDashboardFinder::DASHBOARD_ROOT
}
end
end
diff --git a/app/helpers/form_helper.rb b/app/helpers/form_helper.rb
index 67bfeb22d92..3dde5afcb92 100644
--- a/app/helpers/form_helper.rb
+++ b/app/helpers/form_helper.rb
@@ -55,6 +55,29 @@ module FormHelper
dropdown_data
end
+ def reviewers_dropdown_options(issuable_type)
+ {
+ toggle_class: 'js-reviewer-search js-multiselect js-save-user-data',
+ title: 'Request review from',
+ filter: true,
+ dropdown_class: 'dropdown-menu-user dropdown-menu-selectable dropdown-menu-reviewer',
+ placeholder: _('Search users'),
+ data: {
+ first_user: current_user&.username,
+ null_user: true,
+ current_user: true,
+ project_id: (@target_project || @project)&.id,
+ field_name: "#{issuable_type}[reviewer_ids][]",
+ default_label: 'Unassigned',
+ 'dropdown-header': 'Reviewer(s)',
+ multi_select: true,
+ 'input-meta': 'name',
+ 'always-show-selectbox': true,
+ current_user_info: UserSerializer.new.represent(current_user)
+ }
+ }
+ end
+
# Overwritten
def issue_supports_multiple_assignees?
false
diff --git a/app/helpers/groups/group_members_helper.rb b/app/helpers/groups/group_members_helper.rb
index 1952325c504..dcff2be34da 100644
--- a/app/helpers/groups/group_members_helper.rb
+++ b/app/helpers/groups/group_members_helper.rb
@@ -1,6 +1,10 @@
# frozen_string_literal: true
module Groups::GroupMembersHelper
+ include AvatarsHelper
+
+ AVATAR_SIZE = 40
+
def group_member_select_options
{ multiple: true, class: 'input-clamp qa-member-select-field ', scope: :all, email_user: true }
end
@@ -8,6 +12,81 @@ module Groups::GroupMembersHelper
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
end
+
+ def linked_groups_data_json(group_links)
+ GroupGroupLinkSerializer.new.represent(group_links).to_json
+ end
+
+ def members_data_json(group, members)
+ members_data(group, members).to_json
+ end
+
+ private
+
+ def members_data(group, members)
+ members.map do |member|
+ user = member.user
+ source = member.source
+
+ data = {
+ id: member.id,
+ created_at: member.created_at,
+ expires_at: member.expires_at&.to_time,
+ 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
+ },
+ source: {
+ id: source.id,
+ name: source.full_name,
+ web_url: Gitlab::UrlBuilder.build(source)
+ }
+ }.merge(member_created_by_data(member.created_by))
+
+ if user.present?
+ data[:user] = member_user_data(user)
+ else
+ data[:invite] = member_invite_data(member)
+ end
+
+ data
+ end
+ end
+
+ def member_created_by_data(created_by)
+ return {} unless created_by.present?
+
+ {
+ created_by: {
+ name: created_by.name,
+ web_url: Gitlab::UrlBuilder.build(created_by)
+ }
+ }
+ end
+
+ def member_user_data(user)
+ {
+ id: user.id,
+ name: user.name,
+ username: user.username,
+ web_url: Gitlab::UrlBuilder.build(user),
+ avatar_url: avatar_icon_for_user(user, AVATAR_SIZE),
+ blocked: user.blocked?,
+ two_factor_enabled: user.two_factor_enabled?
+ }
+ end
+
+ def member_invite_data(member)
+ {
+ email: member.invite_email,
+ avatar_url: avatar_icon_for_email(member.invite_email, AVATAR_SIZE),
+ can_resend: member.can_resend_invite?
+ }
+ end
end
Groups::GroupMembersHelper.prepend_if_ee('EE::Groups::GroupMembersHelper')
diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb
index eb80acd869f..06a52457fd6 100644
--- a/app/helpers/groups_helper.rb
+++ b/app/helpers/groups_helper.rb
@@ -167,8 +167,23 @@ module GroupsHelper
@group.packages_feature_enabled?
end
+ def show_invite_banner?(group)
+ Feature.enabled?(:invite_your_teammates_banner_a, group) &&
+ can?(current_user, :admin_group, group) &&
+ !just_created? &&
+ !multiple_members?(group)
+ end
+
private
+ def just_created?
+ flash[:notice] =~ /successfully created/
+ end
+
+ def multiple_members?(group)
+ group.member_count > 1
+ end
+
def get_group_sidebar_links
links = [:overview, :group_members]
diff --git a/app/helpers/icons_helper.rb b/app/helpers/icons_helper.rb
index 9957d5c6330..0352b0ddf28 100644
--- a/app/helpers/icons_helper.rb
+++ b/app/helpers/icons_helper.rb
@@ -100,7 +100,7 @@ module IconsHelper
def boolean_to_icon(value)
if value
- icon('circle', class: 'cgreen')
+ sprite_icon('check', css_class: 'cgreen')
else
sprite_icon('power', css_class: 'clgray')
end
diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb
index 0b859a39c4f..b255597b18d 100644
--- a/app/helpers/issuables_helper.rb
+++ b/app/helpers/issuables_helper.rb
@@ -205,6 +205,12 @@ module IssuablesHelper
author_output
end
+ if access = project.team.human_max_access(issuable.author_id)
+ output << content_tag(:span, access, class: "user-access-role has-tooltip d-none d-xl-inline-block gl-ml-3 ", title: _("This user is a %{access} of the %{name} project.") % { access: access.downcase, name: project.name })
+ elsif project.team.contributor?(issuable.author_id)
+ output << content_tag(:span, _("Contributor"), class: "user-access-role has-tooltip d-none d-xl-inline-block gl-ml-3", title: _("This user has previously committed to the %{name} project.") % { name: project.name })
+ end
+
output << content_tag(:span, (sprite_icon('first-contribution', css_class: 'gl-icon gl-vertical-align-middle') if issuable.first_contribution?), class: 'has-tooltip gl-ml-2', title: _('1st contribution!'))
output << content_tag(:span, (issuable.task_status if issuable.tasks?), id: "task_status", class: "d-none d-sm-none d-md-inline-block gl-ml-3")
@@ -292,8 +298,10 @@ module IssuablesHelper
{
hasClosingMergeRequest: issuable.merge_requests_count(current_user) != 0,
+ issueType: issuable.issue_type,
zoomMeetingUrl: ZoomMeeting.canonical_meeting_url(issuable),
- sentryIssueIdentifier: SentryIssue.find_by(issue: issuable)&.sentry_issue_identifier # rubocop:disable CodeReuse/ActiveRecord
+ sentryIssueIdentifier: SentryIssue.find_by(issue: issuable)&.sentry_issue_identifier, # rubocop:disable CodeReuse/ActiveRecord
+ iid: issuable.iid.to_s
}
end
@@ -301,8 +309,8 @@ module IssuablesHelper
return { groupPath: parent.path } if parent.is_a?(Group)
{
- projectPath: ref_project.path,
- projectNamespace: ref_project.namespace.full_path
+ projectPath: ref_project.path,
+ projectNamespace: ref_project.namespace.full_path
}
end
@@ -464,6 +472,7 @@ module IssuablesHelper
rootPath: root_path,
fullPath: issuable[:project_full_path],
iid: issuable[:iid],
+ severity: issuable[:severity],
timeTrackingLimitToHours: Gitlab::CurrentSettings.time_tracking_limit_to_hours
}
end
diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb
index 55170cbfa6b..e8ea39d7ffc 100644
--- a/app/helpers/issues_helper.rb
+++ b/app/helpers/issues_helper.rb
@@ -4,7 +4,7 @@ module IssuesHelper
def issue_css_classes(issue)
classes = ["issue"]
classes << "closed" if issue.closed?
- classes << "today" if issue.today?
+ classes << "today" if issue.new?
classes << "user-can-drag" if @sort == 'relative_position'
classes.join(' ')
end
diff --git a/app/helpers/lazy_image_tag_helper.rb b/app/helpers/lazy_image_tag_helper.rb
index ac987a04895..0c5744b46ae 100644
--- a/app/helpers/lazy_image_tag_helper.rb
+++ b/app/helpers/lazy_image_tag_helper.rb
@@ -25,5 +25,5 @@ module LazyImageTagHelper
end
# Required for Banzai::Filter::ImageLazyLoadFilter
- module_function :placeholder_image
+ module_function :placeholder_image # rubocop: disable Style/AccessModifierDeclarations
end
diff --git a/app/helpers/nav_helper.rb b/app/helpers/nav_helper.rb
index d849ed9d076..578c7ae7923 100644
--- a/app/helpers/nav_helper.rb
+++ b/app/helpers/nav_helper.rb
@@ -47,7 +47,7 @@ module NavHelper
end
def has_extra_nav_icons?
- Gitlab::Sherlock.enabled? || can?(current_user, :read_instance_statistics) || current_user.admin?
+ Gitlab::Sherlock.enabled? || current_user.admin?
end
def page_has_markdown?
@@ -62,6 +62,10 @@ module NavHelper
%w(system_info background_jobs health_check requests_profiles)
end
+ def admin_analytics_nav_links
+ %w(dev_ops_report cohorts)
+ end
+
def group_issues_sub_menu_items
%w(groups#issues labels#index milestones#index boards#index boards#show)
end
diff --git a/app/helpers/notes_helper.rb b/app/helpers/notes_helper.rb
index 2ba1d841c2e..c02adfcf4c6 100644
--- a/app/helpers/notes_helper.rb
+++ b/app/helpers/notes_helper.rb
@@ -85,6 +85,10 @@ module NotesHelper
note.project.team.max_member_access(note.author_id)
end
+ def note_human_max_access(note)
+ note.project.team.human_max_access(note.author_id)
+ end
+
def discussion_path(discussion)
if discussion.for_merge_request?
return unless discussion.diff_discussion?
@@ -181,7 +185,7 @@ module NotesHelper
reopenPath: reopen_issuable_path(issuable),
notesPath: notes_url,
prerenderedNotesCount: issuable.capped_notes_count(MAX_PRERENDERED_NOTES),
- lastFetchedAt: Time.now.to_i
+ lastFetchedAt: Time.now.to_i * ::Gitlab::UpdatedNotesPaginator::MICROSECOND
}
if issuable.is_a?(MergeRequest)
diff --git a/app/helpers/notifications_helper.rb b/app/helpers/notifications_helper.rb
index 9a64fe98f86..784b242e2b5 100644
--- a/app/helpers/notifications_helper.rb
+++ b/app/helpers/notifications_helper.rb
@@ -6,15 +6,15 @@ module NotificationsHelper
def notification_icon_class(level)
case level.to_sym
when :disabled, :owner_disabled
- 'microphone-slash'
+ 'notifications-off'
when :participating
- 'volume-up'
+ 'notifications'
when :watch
'eye'
when :mention
'at'
when :global
- 'globe'
+ 'earth'
end
end
@@ -28,8 +28,8 @@ module NotificationsHelper
end
end
- def notification_icon(level, text = nil)
- icon("#{notification_icon_class(level)} fw", text: text)
+ def notification_icon(level)
+ sprite_icon("#{notification_icon_class(level)}")
end
def notification_title(level)
diff --git a/app/helpers/operations_helper.rb b/app/helpers/operations_helper.rb
index 37e91153710..521f394a920 100644
--- a/app/helpers/operations_helper.rb
+++ b/app/helpers/operations_helper.rb
@@ -43,6 +43,7 @@ module OperationsHelper
create_issue: setting.create_issue.to_s,
issue_template_key: setting.issue_template_key.to_s,
send_email: setting.send_email.to_s,
+ auto_close_incident: setting.auto_close_incident.to_s,
pagerduty_active: setting.pagerduty_active.to_s,
pagerduty_token: setting.pagerduty_token.to_s,
pagerduty_webhook_url: project_incidents_integrations_pagerduty_url(@project, token: setting.pagerduty_token),
diff --git a/app/helpers/preferences_helper.rb b/app/helpers/preferences_helper.rb
index 5a917a02d51..2c406641882 100644
--- a/app/helpers/preferences_helper.rb
+++ b/app/helpers/preferences_helper.rb
@@ -61,6 +61,10 @@ 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(' ', '_')
+ end
+
def user_color_scheme
Gitlab::ColorSchemes.for_user(current_user).css_class
end
@@ -76,6 +80,13 @@ module PreferencesHelper
)
end
+ def integration_views
+ [].tap do |views|
+ views << 'gitpod' if Gitlab::Gitpod.feature_and_settings_enabled?
+ views << 'sourcegraph' if Gitlab::Sourcegraph.feature_available? && Gitlab::CurrentSettings.sourcegraph_enabled
+ end
+ end
+
private
# Ensure that anyone adding new options updates `DASHBOARD_CHOICES` too
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index 1ce4903f8df..72cc07b13a5 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -7,7 +7,7 @@ module ProjectsHelper
end
def link_to_project(project)
- link_to namespace_project_path(namespace_id: project.namespace, id: project), title: h(project.name) do
+ link_to namespace_project_path(namespace_id: project.namespace, id: project), title: h(project.name), class: 'gl-link' do
title = content_tag(:span, project.name, class: 'project-name')
if project.namespace
@@ -109,7 +109,7 @@ module ProjectsHelper
end
def transfer_project_message(project)
- _("You are going to transfer %{project_full_name} to another owner. Are you ABSOLUTELY sure?") %
+ _("You are going to transfer %{project_full_name} to another namespace. Are you ABSOLUTELY sure?") %
{ project_full_name: project.full_name }
end
@@ -640,7 +640,7 @@ module ProjectsHelper
pagesAvailable: Gitlab.config.pages.enabled,
pagesAccessControlEnabled: Gitlab.config.pages.access_control,
pagesAccessControlForced: ::Gitlab::Pages.access_control_is_forced?,
- pagesHelpPath: help_page_path('user/project/pages/introduction', anchor: 'gitlab-pages-access-control-core')
+ pagesHelpPath: help_page_path('user/project/pages/introduction', anchor: 'gitlab-pages-access-control')
}
end
diff --git a/app/helpers/releases_helper.rb b/app/helpers/releases_helper.rb
index f1dff18523f..979a68ecb7b 100644
--- a/app/helpers/releases_helper.rb
+++ b/app/helpers/releases_helper.rb
@@ -15,6 +15,7 @@ module ReleasesHelper
def data_for_releases_page
{
project_id: @project.id,
+ project_path: @project.full_path,
illustration_path: illustration,
documentation_path: help_page
}.tap do |data|
diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb
index 377aee1ae9e..d55ad878b92 100644
--- a/app/helpers/search_helper.rb
+++ b/app/helpers/search_helper.rb
@@ -1,12 +1,14 @@
# frozen_string_literal: true
module SearchHelper
- SEARCH_PERMITTED_PARAMS = [:search, :scope, :project_id, :group_id, :repository_ref, :snippets].freeze
+ SEARCH_PERMITTED_PARAMS = [:search, :scope, :project_id, :group_id, :repository_ref, :snippets, :state].freeze
def search_autocomplete_opts(term)
return unless current_user
resources_results = [
+ recent_merge_requests_autocomplete(term),
+ recent_issues_autocomplete(term),
groups_autocomplete(term),
projects_autocomplete(term)
].flatten
@@ -178,6 +180,34 @@ module SearchHelper
}
end
end
+
+ def recent_merge_requests_autocomplete(term, limit = 5)
+ return [] unless current_user
+
+ ::Gitlab::Search::RecentMergeRequests.new(user: current_user).search(term).limit(limit).map do |mr|
+ {
+ category: "Recent merge requests",
+ id: mr.id,
+ label: search_result_sanitize(mr.title),
+ url: merge_request_path(mr),
+ avatar_url: mr.project.avatar_url || ''
+ }
+ end
+ end
+
+ def recent_issues_autocomplete(term, limit = 5)
+ return [] unless current_user
+
+ ::Gitlab::Search::RecentIssues.new(user: current_user).search(term).limit(limit).map do |i|
+ {
+ category: "Recent issues",
+ id: i.id,
+ label: search_result_sanitize(i.title),
+ url: issue_path(i),
+ avatar_url: i.project.avatar_url || ''
+ }
+ end
+ end
# rubocop: enable CodeReuse/ActiveRecord
def search_result_sanitize(str)
@@ -250,15 +280,16 @@ module SearchHelper
# Sanitize a HTML field for search display. Most tags are stripped out and the
# maximum length is set to 200 characters.
- def search_md_sanitize(object, field)
- html = markdown_field(object, field)
- html = Truncato.truncate(
- html,
+ def search_md_sanitize(source)
+ source = Truncato.truncate(
+ source,
count_tags: false,
count_tail: false,
max_length: 200
)
+ html = markdown(source)
+
# Truncato's filtered_tags and filtered_attributes are not quite the same
sanitize(html, tags: %w(a p ol ul li pre code))
end
diff --git a/app/helpers/services_helper.rb b/app/helpers/services_helper.rb
index e9d39cc8175..6b5de73a831 100644
--- a/app/helpers/services_helper.rb
+++ b/app/helpers/services_helper.rb
@@ -92,9 +92,15 @@ module ServicesHelper
commit_events: integration.commit_events.to_s,
enable_comments: integration.comment_on_event_enabled.to_s,
comment_detail: integration.comment_detail,
+ learn_more_path: integrations_help_page_path,
trigger_events: trigger_events_for_service(integration),
fields: fields_for_service(integration),
- inherit_from_id: integration.inherit_from_id
+ inherit_from_id: integration.inherit_from_id,
+ integration_level: integration_level(integration),
+ editable: integration.editable?.to_s,
+ cancel_path: scoped_integrations_path,
+ can_test: integration.can_test?.to_s,
+ test_path: scoped_test_integration_path(integration)
}
end
@@ -106,11 +112,31 @@ module ServicesHelper
ServiceFieldSerializer.new(service: integration).represent(integration.global_fields).to_json
end
+ def integrations_help_page_path
+ help_page_path('user/admin_area/settings/project_integration_management')
+ end
+
def project_jira_issues_integration?
false
end
+ def group_level_integrations?
+ @group.present? && Feature.enabled?(:group_level_integrations, @group)
+ end
+
extend self
+
+ private
+
+ def integration_level(integration)
+ if integration.instance
+ 'instance'
+ elsif integration.group_id
+ 'group'
+ else
+ 'project'
+ end
+ end
end
ServicesHelper.prepend_if_ee('EE::ServicesHelper')
diff --git a/app/helpers/snippets_helper.rb b/app/helpers/snippets_helper.rb
index 10c95da394f..94c46feb8ae 100644
--- a/app/helpers/snippets_helper.rb
+++ b/app/helpers/snippets_helper.rb
@@ -12,7 +12,7 @@ module SnippetsHelper
end
def download_raw_snippet_button(snippet)
- link_to(icon('download'),
+ link_to(sprite_icon('download'),
gitlab_raw_snippet_path(snippet, inline: false),
target: '_blank',
rel: 'noopener noreferrer',
diff --git a/app/helpers/startup_css_helper.rb b/app/helpers/startup_css_helper.rb
new file mode 100644
index 00000000000..b54e19bfc0d
--- /dev/null
+++ b/app/helpers/startup_css_helper.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+module StartupCssHelper
+ def use_startup_css?
+ (Feature.enabled?(:startup_css) || params[:startup_css] == 'true' || cookies['startup_css'] == 'true') && !Rails.env.test?
+ end
+end
diff --git a/app/helpers/submodule_helper.rb b/app/helpers/submodule_helper.rb
index 06ea3dd8a81..959178c47d7 100644
--- a/app/helpers/submodule_helper.rb
+++ b/app/helpers/submodule_helper.rb
@@ -6,19 +6,19 @@ module SubmoduleHelper
VALID_SUBMODULE_PROTOCOLS = %w[http https git ssh].freeze
# links to files listing for submodule if submodule is a project on this server
- def submodule_links(submodule_item, ref = nil, repository = @repository)
- repository.submodule_links.for(submodule_item, ref)
+ def submodule_links(submodule_item, ref = nil, repository = @repository, diff_file = nil)
+ repository.submodule_links.for(submodule_item, ref, diff_file)
end
- def submodule_links_for_url(submodule_item_id, url, repository)
- return [nil, nil] unless url
+ def submodule_links_for_url(submodule_item_id, url, repository, old_submodule_item_id = nil)
+ return [nil, nil, nil] unless url
if url == '.' || url == './'
url = File.join(Gitlab.config.gitlab.url, repository.project.full_path)
end
if url =~ %r{([^/:]+)/([^/]+(?:\.git)?)\Z}
- namespace, project = $1, $2
+ namespace, project = Regexp.last_match(1), Regexp.last_match(2)
gitlab_hosts = [Gitlab.config.gitlab.url,
Gitlab.config.gitlab_shell.ssh_path_prefix]
@@ -34,21 +34,24 @@ module SubmoduleHelper
project.sub!(/\.git\z/, '')
if self_url?(url, namespace, project)
- [url_helpers.namespace_project_path(namespace, project),
- url_helpers.namespace_project_tree_path(namespace, project, submodule_item_id)]
+ [
+ url_helpers.namespace_project_path(namespace, project),
+ url_helpers.namespace_project_tree_path(namespace, project, submodule_item_id),
+ (url_helpers.namespace_project_compare_path(namespace, project, to: submodule_item_id, from: old_submodule_item_id) if old_submodule_item_id)
+ ]
elsif relative_self_url?(url)
- relative_self_links(url, submodule_item_id, repository.project)
+ relative_self_links(url, submodule_item_id, old_submodule_item_id, repository.project)
elsif gist_github_dot_com_url?(url)
gist_github_com_tree_links(namespace, project, submodule_item_id)
elsif github_dot_com_url?(url)
- github_com_tree_links(namespace, project, submodule_item_id)
+ github_com_tree_links(namespace, project, submodule_item_id, old_submodule_item_id)
elsif gitlab_dot_com_url?(url)
- gitlab_com_tree_links(namespace, project, submodule_item_id)
+ gitlab_com_tree_links(namespace, project, submodule_item_id, old_submodule_item_id)
else
- [sanitize_submodule_url(url), nil]
+ [sanitize_submodule_url(url), nil, nil]
end
else
- [sanitize_submodule_url(url), nil]
+ [sanitize_submodule_url(url), nil, nil]
end
end
@@ -79,22 +82,30 @@ module SubmoduleHelper
url.start_with?('../', './')
end
- def gitlab_com_tree_links(namespace, project, commit)
+ def gitlab_com_tree_links(namespace, project, commit, old_commit)
base = ['https://gitlab.com/', namespace, '/', project].join('')
- [base, [base, '/-/tree/', commit].join('')]
+ [
+ base,
+ [base, '/-/tree/', commit].join(''),
+ ([base, '/-/compare/', old_commit, '...', commit].join('') if old_commit)
+ ]
end
def gist_github_com_tree_links(namespace, project, commit)
base = ['https://gist.github.com/', namespace, '/', project].join('')
- [base, [base, commit].join('/')]
+ [base, [base, commit].join('/'), nil]
end
- def github_com_tree_links(namespace, project, commit)
+ def github_com_tree_links(namespace, project, commit, old_commit)
base = ['https://github.com/', namespace, '/', project].join('')
- [base, [base, '/tree/', commit].join('')]
+ [
+ base,
+ [base, '/tree/', commit].join(''),
+ ([base, '/compare/', old_commit, '...', commit].join('') if old_commit)
+ ]
end
- def relative_self_links(relative_path, commit, project)
+ def relative_self_links(relative_path, commit, old_commit, project)
relative_path = relative_path.rstrip
absolute_project_path = "/" + project.full_path
@@ -107,7 +118,7 @@ module SubmoduleHelper
target_namespace_path = File.dirname(submodule_project_path)
if target_namespace_path == '/' || target_namespace_path.start_with?(absolute_project_path)
- return [nil, nil]
+ return [nil, nil, nil]
end
target_namespace_path.sub!(%r{^/}, '')
@@ -116,10 +127,11 @@ module SubmoduleHelper
begin
[
url_helpers.namespace_project_path(target_namespace_path, submodule_base),
- url_helpers.namespace_project_tree_path(target_namespace_path, submodule_base, commit)
+ url_helpers.namespace_project_tree_path(target_namespace_path, submodule_base, commit),
+ (url_helpers.namespace_project_compare_path(target_namespace_path, submodule_base, to: commit, from: old_commit) if old_commit)
]
rescue ActionController::UrlGenerationError
- [nil, nil]
+ [nil, nil, nil]
end
end
diff --git a/app/helpers/system_note_helper.rb b/app/helpers/system_note_helper.rb
index 6ea6a33ba5e..0227ad1092d 100644
--- a/app/helpers/system_note_helper.rb
+++ b/app/helpers/system_note_helper.rb
@@ -7,7 +7,7 @@ module SystemNoteHelper
'description' => 'pencil-square',
'merge' => 'git-merge',
'merged' => 'git-merge',
- 'opened' => 'issue-open',
+ 'opened' => 'issues',
'closed' => 'issue-close',
'time_tracking' => 'timer',
'assignee' => 'user',
@@ -33,7 +33,8 @@ module SystemNoteHelper
'designs_removed' => 'doc-image',
'designs_discussion_added' => 'doc-image',
'status' => 'status',
- 'alert_issue_added' => 'issues'
+ 'alert_issue_added' => 'issues',
+ 'new_alert_added' => 'warning'
}.freeze
def system_note_icon_name(note)
diff --git a/app/helpers/tab_helper.rb b/app/helpers/tab_helper.rb
index 0f156003a01..6fbe2642056 100644
--- a/app/helpers/tab_helper.rb
+++ b/app/helpers/tab_helper.rb
@@ -127,5 +127,3 @@ module TabHelper
end
end
end
-
-TabHelper.prepend_if_ee('EE::TabHelper')
diff --git a/app/helpers/tree_helper.rb b/app/helpers/tree_helper.rb
index 90a5b6da4c7..7644ed783eb 100644
--- a/app/helpers/tree_helper.rb
+++ b/app/helpers/tree_helper.rb
@@ -191,16 +191,46 @@ module TreeHelper
def vue_file_list_data(project, ref)
{
- can_push_code: current_user&.can?(:push_code, project) && "true",
project_path: project.full_path,
project_short_path: project.path,
- fork_path: current_user&.fork_of(project)&.full_path,
ref: ref,
escaped_ref: ActionDispatch::Journey::Router::Utils.escape_path(ref),
full_name: project.name_with_namespace
}
end
+ def ide_base_path(project)
+ can_push_code = current_user&.can?(:push_code, project)
+ fork_path = current_user&.fork_of(project)&.full_path
+
+ if can_push_code
+ project.full_path
+ else
+ fork_path || project.full_path
+ end
+ end
+
+ 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)
+
+ {
+ 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
+ }
+ 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 98159369fb1..967271a8431 100644
--- a/app/helpers/user_callouts_helper.rb
+++ b/app/helpers/user_callouts_helper.rb
@@ -5,9 +5,11 @@ module UserCalloutsHelper
GKE_CLUSTER_INTEGRATION = 'gke_cluster_integration'
GCP_SIGNUP_OFFER = 'gcp_signup_offer'
SUGGEST_POPOVER_DISMISSED = 'suggest_popover_dismissed'
+ SERVICE_TEMPLATES_DEPRECATED = 'service_templates_deprecated'
TABS_POSITION_HIGHLIGHT = 'tabs_position_highlight'
WEBHOOKS_MOVED = 'webhooks_moved'
CUSTOMIZE_HOMEPAGE = 'customize_homepage'
+ WEB_IDE_ALERT_DISMISSED = 'web_ide_alert_dismissed'
def show_admin_integrations_moved?
!user_dismissed?(ADMIN_INTEGRATIONS_MOVED)
@@ -37,6 +39,10 @@ module UserCalloutsHelper
!user_dismissed?(SUGGEST_POPOVER_DISMISSED)
end
+ def show_service_templates_deprecated?
+ !user_dismissed?(SERVICE_TEMPLATES_DEPRECATED)
+ end
+
def show_webhooks_moved_alert?
!user_dismissed?(WEBHOOKS_MOVED)
end
@@ -45,6 +51,10 @@ module UserCalloutsHelper
customize_homepage && !user_dismissed?(CUSTOMIZE_HOMEPAGE)
end
+ def show_web_ide_alert?
+ !user_dismissed?(WEB_IDE_ALERT_DISMISSED)
+ end
+
private
def user_dismissed?(feature_name, ignore_dismissal_earlier_than = nil)
diff --git a/app/helpers/whats_new_helper.rb b/app/helpers/whats_new_helper.rb
new file mode 100644
index 00000000000..f0044daa645
--- /dev/null
+++ b/app/helpers/whats_new_helper.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module WhatsNewHelper
+ EMPTY_JSON = ''.to_json
+
+ def whats_new_most_recent_release_items
+ YAML.load_file(most_recent_release_file_path).to_json
+
+ rescue => e
+ Gitlab::ErrorTracking.track_exception(e, yaml_file_path: most_recent_release_file_path)
+
+ EMPTY_JSON
+ end
+
+ private
+
+ def most_recent_release_file_path
+ Dir.glob(files_path).max
+ end
+
+ def files_path
+ Rails.root.join('data', 'whats_new', '*.yml')
+ end
+end
diff --git a/app/helpers/wiki_helper.rb b/app/helpers/wiki_helper.rb
index ad33ac66f38..8c756b9370b 100644
--- a/app/helpers/wiki_helper.rb
+++ b/app/helpers/wiki_helper.rb
@@ -69,7 +69,12 @@ module WikiHelper
end
def wiki_attachment_upload_url
- expose_url(api_v4_projects_wikis_attachments_path(id: @wiki.container.id))
+ case @wiki.container
+ when Project
+ expose_url(api_v4_projects_wikis_attachments_path(id: @wiki.container.id))
+ else
+ raise TypeError, "Unsupported wiki container #{@wiki.container.class}"
+ end
end
def wiki_sort_controls(wiki, sort, direction)
@@ -147,3 +152,5 @@ module WikiHelper
!container.has_confluence?
end
end
+
+WikiHelper.prepend_if_ee('EE::WikiHelper')