summaryrefslogtreecommitdiff
path: root/app/helpers
diff options
context:
space:
mode:
Diffstat (limited to 'app/helpers')
-rw-r--r--app/helpers/admin/user_actions_helper.rb56
-rw-r--r--app/helpers/application_helper.rb8
-rw-r--r--app/helpers/application_settings_helper.rb10
-rw-r--r--app/helpers/auth_helper.rb4
-rw-r--r--app/helpers/blob_helper.rb14
-rw-r--r--app/helpers/button_helper.rb10
-rw-r--r--app/helpers/ci/pipeline_schedules_helper.rb15
-rw-r--r--app/helpers/ci/runners_helper.rb16
-rw-r--r--app/helpers/container_registry_helper.rb4
-rw-r--r--app/helpers/defer_script_tag_helper.rb10
-rw-r--r--app/helpers/diff_helper.rb8
-rw-r--r--app/helpers/dropdowns_helper.rb2
-rw-r--r--app/helpers/environment_helper.rb2
-rw-r--r--app/helpers/events_helper.rb2
-rw-r--r--app/helpers/form_helper.rb10
-rw-r--r--app/helpers/gitlab_script_tag_helper.rb24
-rw-r--r--app/helpers/groups/group_members_helper.rb3
-rw-r--r--app/helpers/groups_helper.rb5
-rw-r--r--app/helpers/icons_helper.rb20
-rw-r--r--app/helpers/issuables_helper.rb66
-rw-r--r--app/helpers/issues_helper.rb8
-rw-r--r--app/helpers/markup_helper.rb27
-rw-r--r--app/helpers/merge_requests_helper.rb21
-rw-r--r--app/helpers/notifications_helper.rb3
-rw-r--r--app/helpers/notify_helper.rb4
-rw-r--r--app/helpers/operations_helper.rb10
-rw-r--r--app/helpers/profiles_helper.rb6
-rw-r--r--app/helpers/projects/alert_management_helper.rb2
-rw-r--r--app/helpers/projects/terraform_helper.rb5
-rw-r--r--app/helpers/projects_helper.rb19
-rw-r--r--app/helpers/search_helper.rb4
-rw-r--r--app/helpers/services_helper.rb20
-rw-r--r--app/helpers/sorting_helper.rb367
-rw-r--r--app/helpers/sorting_titles_values_helper.rb339
-rw-r--r--app/helpers/storage_helper.rb6
-rw-r--r--app/helpers/suggest_pipeline_helper.rb4
-rw-r--r--app/helpers/system_note_helper.rb3
-rw-r--r--app/helpers/time_zone_helper.rb34
-rw-r--r--app/helpers/tree_helper.rb4
-rw-r--r--app/helpers/user_callouts_helper.rb5
-rw-r--r--app/helpers/users_helper.rb93
-rw-r--r--app/helpers/visibility_level_helper.rb10
-rw-r--r--app/helpers/web_ide_button_helper.rb12
-rw-r--r--app/helpers/whats_new_helper.rb20
44 files changed, 737 insertions, 578 deletions
diff --git a/app/helpers/admin/user_actions_helper.rb b/app/helpers/admin/user_actions_helper.rb
new file mode 100644
index 00000000000..cd520a75b44
--- /dev/null
+++ b/app/helpers/admin/user_actions_helper.rb
@@ -0,0 +1,56 @@
+# frozen_string_literal: true
+
+module Admin
+ module UserActionsHelper
+ def admin_actions(user)
+ return [] if user.internal?
+
+ @actions ||= ['edit']
+
+ return @actions if user == current_user
+
+ @user ||= user
+
+ blocked_actions
+ deactivate_actions
+ unlock_actions
+ delete_actions
+
+ @actions
+ end
+
+ private
+
+ def blocked_actions
+ if @user.ldap_blocked?
+ @actions << 'ldap'
+ elsif @user.blocked? && @user.blocked_pending_approval?
+ @actions << 'approve'
+ @actions << 'reject'
+ elsif @user.blocked?
+ @actions << 'unblock'
+ else
+ @actions << 'block'
+ end
+ end
+
+ def deactivate_actions
+ if @user.can_be_deactivated?
+ @actions << 'deactivate'
+ elsif @user.deactivated?
+ @actions << 'activate'
+ end
+ end
+
+ def unlock_actions
+ @actions << 'unlock' if @user.access_locked?
+ end
+
+ def delete_actions
+ return unless can?(current_user, :destroy_user, @user) && !@user.blocked_pending_approval? && @user.can_be_removed?
+
+ @actions << 'delete'
+ @actions << 'delete_with_contributions'
+ end
+ end
+end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 2a6b00c0bd8..512ba7e2a66 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -361,9 +361,13 @@ module ApplicationHelper
}
end
- def add_page_specific_style(path)
+ def add_page_specific_style(path, defer: true)
content_for :page_specific_styles do
- stylesheet_link_tag_defer path
+ if defer
+ stylesheet_link_tag_defer path
+ else
+ stylesheet_link_tag path
+ end
end
end
diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb
index 512649b3008..7866e3e3d9f 100644
--- a/app/helpers/application_settings_helper.rb
+++ b/app/helpers/application_settings_helper.rb
@@ -49,12 +49,12 @@ module ApplicationSettingsHelper
all_protocols_enabled? || Gitlab::CurrentSettings.enabled_git_access_protocol == 'http'
end
- def enabled_project_button(project, protocol)
+ def enabled_protocol_button(container, protocol)
case protocol
when 'ssh'
- ssh_clone_button(project, append_link: false)
+ ssh_clone_button(container, append_link: false)
else
- http_clone_button(project, append_link: false)
+ http_clone_button(container, append_link: false)
end
end
@@ -198,6 +198,7 @@ module ApplicationSettingsHelper
:default_project_visibility,
:default_projects_limit,
:default_snippet_visibility,
+ :disable_feed_token,
:disabled_oauth_sign_in_sources,
:domain_denylist,
:domain_denylist_enabled,
@@ -254,6 +255,9 @@ module ApplicationSettingsHelper
:password_authentication_enabled_for_git,
:performance_bar_allowed_group_path,
:performance_bar_enabled,
+ :personal_access_token_prefix,
+ :kroki_enabled,
+ :kroki_url,
:plantuml_enabled,
:plantuml_url,
:polling_interval_multiplier,
diff --git a/app/helpers/auth_helper.rb b/app/helpers/auth_helper.rb
index cc43ea85a11..0b79d4c36a1 100644
--- a/app/helpers/auth_helper.rb
+++ b/app/helpers/auth_helper.rb
@@ -113,6 +113,10 @@ module AuthHelper
end
end
+ def experiment_enabled_button_based_providers
+ enabled_button_based_providers & %w(google_oauth2 github).freeze
+ end
+
def button_based_providers_enabled?
enabled_button_based_providers.any?
end
diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb
index 981b5e4d92b..0c5823894c5 100644
--- a/app/helpers/blob_helper.rb
+++ b/app/helpers/blob_helper.rb
@@ -1,10 +1,6 @@
# frozen_string_literal: true
module BlobHelper
- def no_highlight_files
- %w(credits changelog news copying copyright license authors)
- end
-
def edit_blob_path(project = @project, ref = @ref, path = @path, options = {})
project_edit_blob_path(project,
tree_join(ref, path),
@@ -246,7 +242,7 @@ module BlobHelper
def copy_blob_source_button(blob)
return unless blob.rendered_as_text?(ignore_errors: false)
- clipboard_button(target: ".blob-content[data-blob-id='#{blob.id}']", class: "btn btn-sm js-copy-blob-source-btn", title: _("Copy file contents"))
+ clipboard_button(target: ".blob-content[data-blob-id='#{blob.id}'] > pre", class: "btn btn-sm js-copy-blob-source-btn", title: _("Copy file contents"))
end
def open_raw_blob_button(blob)
@@ -332,8 +328,9 @@ module BlobHelper
end
def readable_blob(options, path, project, ref)
- blob = options.delete(:blob)
- blob ||= project.repository.blob_at(ref, path) rescue nil
+ blob = options.fetch(:blob) do
+ project.repository.blob_at(ref, path) rescue nil
+ end
blob if blob&.readable_text?
end
@@ -382,8 +379,7 @@ module BlobHelper
end
def show_suggest_pipeline_creation_celebration?
- Feature.enabled?(:suggest_pipeline, default_enabled: true) &&
- @blob.path == Gitlab::FileDetector::PATTERNS[:gitlab_ci] &&
+ @blob.path == Gitlab::FileDetector::PATTERNS[:gitlab_ci] &&
@blob.auxiliary_viewer&.valid?(project: @project, sha: @commit.sha, user: current_user) &&
@project.uses_default_ci_config? &&
cookies[suggest_pipeline_commit_cookie_name].present?
diff --git a/app/helpers/button_helper.rb b/app/helpers/button_helper.rb
index c999d1f94ad..ea24f469ffa 100644
--- a/app/helpers/button_helper.rb
+++ b/app/helpers/button_helper.rb
@@ -58,10 +58,10 @@ module ButtonHelper
end
end
- def http_clone_button(project, append_link: true)
+ def http_clone_button(container, append_link: true)
protocol = gitlab_config.protocol.upcase
dropdown_description = http_dropdown_description(protocol)
- append_url = project.http_url_to_repo if append_link
+ append_url = container.http_url_to_repo if append_link
dropdown_item_with_description(protocol, dropdown_description, href: append_url, data: { clone_type: 'http' })
end
@@ -74,13 +74,13 @@ module ButtonHelper
end
end
- def ssh_clone_button(project, append_link: true)
+ def ssh_clone_button(container, append_link: true)
if Gitlab::CurrentSettings.user_show_add_ssh_key_message? &&
current_user.try(:require_ssh_key?)
- dropdown_description = _("You won't be able to pull or push project code via SSH until you add an SSH key to your profile")
+ dropdown_description = s_("MissingSSHKeyWarningLink|You won't be able to pull or push repositories via SSH until you add an SSH key to your profile")
end
- append_url = project.ssh_url_to_repo if append_link
+ append_url = container.ssh_url_to_repo if append_link
dropdown_item_with_description('SSH', dropdown_description, href: append_url, data: { clone_type: 'ssh' })
end
diff --git a/app/helpers/ci/pipeline_schedules_helper.rb b/app/helpers/ci/pipeline_schedules_helper.rb
deleted file mode 100644
index 20e5c90a60e..00000000000
--- a/app/helpers/ci/pipeline_schedules_helper.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-# frozen_string_literal: true
-
-module Ci
- module PipelineSchedulesHelper
- def timezone_data
- ActiveSupport::TimeZone.all.map do |timezone|
- {
- name: timezone.name,
- offset: timezone.now.utc_offset,
- identifier: timezone.tzinfo.identifier
- }
- end
- end
- end
-end
diff --git a/app/helpers/ci/runners_helper.rb b/app/helpers/ci/runners_helper.rb
index 432aad663e4..ba5d4e8c65a 100644
--- a/app/helpers/ci/runners_helper.rb
+++ b/app/helpers/ci/runners_helper.rb
@@ -8,14 +8,14 @@ module Ci
status = runner.status
case status
when :not_connected
- content_tag(:span, title: "New runner. Has not connected yet") do
+ content_tag(:span, title: _("New runner. Has not connected yet")) do
sprite_icon("warning-solid", size: 24, css_class: "gl-vertical-align-bottom!")
end
when :online, :offline, :paused
- content_tag :i, nil,
- class: "fa fa-circle runner-status-#{status}",
- title: "Runner is #{status}, last contact was #{time_ago_in_words(runner.contacted_at)} ago"
+ content_tag :span, nil,
+ class: "gl-display-inline-block gl-avatar gl-avatar-s16 gl-avatar-circle runner-status runner-status-#{status}",
+ title: _("Runner is %{status}, last contact was %{runner_contact} ago") % { status: status, runner_contact: time_ago_in_words(runner.contacted_at) }
end
end
@@ -49,6 +49,14 @@ module Ci
parent_shared_runners_availability: group.parent&.shared_runners_setting
}
end
+
+ def toggle_shared_runners_settings_data(project)
+ {
+ is_enabled: "#{project.shared_runners_enabled?}",
+ is_disabled_and_unoverridable: "#{project.group&.shared_runners_setting == 'disabled_and_unoverridable'}",
+ update_path: toggle_shared_runners_project_runners_path(project)
+ }
+ end
end
end
diff --git a/app/helpers/container_registry_helper.rb b/app/helpers/container_registry_helper.rb
index 9a5d84a90dd..0efc8c50d58 100644
--- a/app/helpers/container_registry_helper.rb
+++ b/app/helpers/container_registry_helper.rb
@@ -5,4 +5,8 @@ module ContainerRegistryHelper
Feature.enabled?(:container_registry_expiration_policies_throttling) &&
ContainerRegistry::Client.supports_tag_delete?
end
+
+ def container_repository_gid_prefix
+ "gid://#{GlobalID.app}/#{ContainerRepository.name}/"
+ end
end
diff --git a/app/helpers/defer_script_tag_helper.rb b/app/helpers/defer_script_tag_helper.rb
deleted file mode 100644
index be927c67aaa..00000000000
--- a/app/helpers/defer_script_tag_helper.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-# frozen_string_literal: true
-
-module DeferScriptTagHelper
- # Override the default ActionView `javascript_include_tag` helper to support page specific deferred loading.
- # PLEASE NOTE: `defer` is also critical so that we don't run JavaScript entrypoints before the DOM is ready.
- # Please see https://gitlab.com/groups/gitlab-org/-/epics/4538#note_432159769.
- def javascript_include_tag(*sources)
- super(*sources, defer: true)
- end
-end
diff --git a/app/helpers/diff_helper.rb b/app/helpers/diff_helper.rb
index d6d06434590..69a2efebb1f 100644
--- a/app/helpers/diff_helper.rb
+++ b/app/helpers/diff_helper.rb
@@ -203,14 +203,6 @@ module DiffHelper
set_secure_cookie(:diff_view, params.delete(:view), type: CookiesHelper::COOKIE_TYPE_PERMANENT) if params[:view].present?
end
- def unified_diff_lines_view_type(project)
- if Feature.enabled?(:unified_diff_lines, project, default_enabled: true)
- 'inline'
- else
- diff_view
- end
- end
-
private
def diff_btn(title, name, selected)
diff --git a/app/helpers/dropdowns_helper.rb b/app/helpers/dropdowns_helper.rb
index e10e9a83b05..45f5281b515 100644
--- a/app/helpers/dropdowns_helper.rb
+++ b/app/helpers/dropdowns_helper.rb
@@ -51,7 +51,7 @@ module DropdownsHelper
default_label = data_attr[:default_label]
content_tag(:button, disabled: options[:disabled], class: "dropdown-menu-toggle #{options[:toggle_class] if options.key?(:toggle_class)}", id: (options[:id] if options.key?(:id)), type: "button", data: data_attr) do
output = content_tag(:span, toggle_text, class: "dropdown-toggle-text #{'is-default' if toggle_text == default_label}")
- output << icon('chevron-down')
+ output << sprite_icon('chevron-down', css_class: "dropdown-menu-toggle-icon gl-top-3")
output.html_safe
end
end
diff --git a/app/helpers/environment_helper.rb b/app/helpers/environment_helper.rb
index c4487ae8e4a..491d2731e91 100644
--- a/app/helpers/environment_helper.rb
+++ b/app/helpers/environment_helper.rb
@@ -52,6 +52,8 @@ module EnvironmentHelper
s_('Deployment|failed')
when 'canceled'
s_('Deployment|canceled')
+ when 'skipped'
+ s_('Deployment|skipped')
end
klass = "ci-status ci-#{status.dasherize}"
diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb
index f40755b9439..e6603237676 100644
--- a/app/helpers/events_helper.rb
+++ b/app/helpers/events_helper.rb
@@ -256,7 +256,7 @@ module EventsHelper
end
else
content_tag :div, class: 'system-note-image user-avatar' do
- author_avatar(event, size: 40)
+ author_avatar(event, size: 32)
end
end
end
diff --git a/app/helpers/form_helper.rb b/app/helpers/form_helper.rb
index 8a8d708b0b2..d0276c91316 100644
--- a/app/helpers/form_helper.rb
+++ b/app/helpers/form_helper.rb
@@ -55,7 +55,7 @@ module FormHelper
dropdown_data
end
- def reviewers_dropdown_options(issuable_type)
+ def reviewers_dropdown_options(issuable_type, iid = nil, target_branch = nil)
dropdown_data = {
toggle_class: 'js-reviewer-search js-multiselect js-save-user-data',
title: 'Request review from',
@@ -78,6 +78,14 @@ module FormHelper
}
}
+ if iid
+ dropdown_data[:data][:iid] = iid
+ end
+
+ if target_branch
+ dropdown_data[:data][:target_branch] = target_branch
+ end
+
if merge_request_supports_multiple_reviewers?
dropdown_data = multiple_reviewers_dropdown_options(dropdown_data)
end
diff --git a/app/helpers/gitlab_script_tag_helper.rb b/app/helpers/gitlab_script_tag_helper.rb
new file mode 100644
index 00000000000..467f3f7305b
--- /dev/null
+++ b/app/helpers/gitlab_script_tag_helper.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module GitlabScriptTagHelper
+ # Override the default ActionView `javascript_include_tag` helper to support page specific deferred loading.
+ # PLEASE NOTE: `defer` is also critical so that we don't run JavaScript entrypoints before the DOM is ready.
+ # Please see https://gitlab.com/groups/gitlab-org/-/epics/4538#note_432159769.
+ # The helper also makes sure the `nonce` attribute is included in every script when the content security
+ # policy is enabled.
+ def javascript_include_tag(*sources)
+ super(*sources, defer: true, nonce: true)
+ end
+
+ # The helper makes sure the `nonce` attribute is included in every script when the content security
+ # policy is enabled.
+ def javascript_tag(content_or_options_with_block = nil, html_options = {})
+ if content_or_options_with_block.is_a?(Hash)
+ content_or_options_with_block[:nonce] = true
+ else
+ html_options[:nonce] = true
+ end
+
+ super
+ end
+end
diff --git a/app/helpers/groups/group_members_helper.rb b/app/helpers/groups/group_members_helper.rb
index ee90585112b..adc9d85a384 100644
--- a/app/helpers/groups/group_members_helper.rb
+++ b/app/helpers/groups/group_members_helper.rb
@@ -26,7 +26,8 @@ module Groups::GroupMembersHelper
{
members: members_data_json(group, members),
member_path: group_group_member_path(group, ':id'),
- group_id: group.id
+ group_id: group.id,
+ can_manage_members: can?(current_user, :admin_group_member, group).to_s
}
end
diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb
index 29ead76a607..e8eb6a5d417 100644
--- a/app/helpers/groups_helper.rb
+++ b/app/helpers/groups_helper.rb
@@ -21,7 +21,6 @@ module GroupsHelper
integrations#edit
ldap_group_links#index
hooks#index
- audit_events#index
pipeline_quota#index
]
end
@@ -189,6 +188,10 @@ module GroupsHelper
params.key?(:purchased_quantity) && params[:purchased_quantity].to_i > 0
end
+ def project_list_sort_by
+ @group_projects_sort || @sort || params[:sort] || sort_value_recently_created
+ end
+
private
def just_created?
diff --git a/app/helpers/icons_helper.rb b/app/helpers/icons_helper.rb
index dc6164ee898..096a3f2269b 100644
--- a/app/helpers/icons_helper.rb
+++ b/app/helpers/icons_helper.rb
@@ -4,25 +4,9 @@ require 'json'
module IconsHelper
extend self
- include FontAwesome::Rails::IconHelper
DEFAULT_ICON_SIZE = 16
- # Creates an icon tag given icon name(s) and possible icon modifiers.
- #
- # Right now this method simply delegates directly to `fa_icon` from the
- # font-awesome-rails gem, but should we ever use a different icon pack in the
- # future we won't have to change hundreds of method calls.
- def icon(names, options = {})
- if (options.keys & %w[aria-hidden aria-label data-hidden]).empty?
- # Add 'aria-hidden' and 'data-hidden' if they are not set in options.
- options['aria-hidden'] = true
- options['data-hidden'] = true
- end
-
- options.include?(:base) ? fa_stacked_icon(names, options) : fa_icon(names, options)
- end
-
def custom_icon(icon_name, size: DEFAULT_ICON_SIZE)
memoized_icon("#{icon_name}_#{size}") do
# We can't simply do the below, because there are some .erb SVGs.
@@ -95,9 +79,9 @@ module IconsHelper
def boolean_to_icon(value)
if value
- sprite_icon('check', css_class: 'cgreen')
+ sprite_icon('check', css_class: 'gl-text-green-500')
else
- sprite_icon('power', css_class: 'clgray')
+ sprite_icon('power', css_class: 'gl-text-gray-500')
end
end
diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb
index 77ced17bc22..15842dec3dd 100644
--- a/app/helpers/issuables_helper.rb
+++ b/app/helpers/issuables_helper.rb
@@ -61,16 +61,6 @@ module IssuablesHelper
end
end
- def issuable_json_path(issuable)
- project = issuable.project
-
- if issuable.is_a?(MergeRequest)
- project_merge_request_path(project, issuable.iid, :json)
- else
- project_issue_path(project, issuable.iid, :json)
- end
- end
-
def serialize_issuable(issuable, opts = {})
serializer_klass = case issuable
when Issue
@@ -174,30 +164,26 @@ module IssuablesHelper
h(title || default_label)
end
- def to_url_reference(issuable)
- case issuable
- when Issue
- link_to issuable.to_reference, issue_url(issuable)
- when MergeRequest
- link_to issuable.to_reference, merge_request_url(issuable)
- else
- issuable.to_reference
- end
+ def issuable_meta_author_status(author)
+ return "" unless show_status_emoji?(author&.status) && status = user_status(author)
+
+ "#{status}".html_safe
end
- def issuable_meta(issuable, project, text)
+ def issuable_meta(issuable, project)
output = []
output << "Opened #{time_ago_with_tooltip(issuable.created_at)} by ".html_safe
+ if issuable.is_a?(Issue) && issuable.service_desk_reply_to
+ output << "#{html_escape(issuable.service_desk_reply_to)} via "
+ end
+
output << content_tag(:strong) do
author_output = link_to_member(project, issuable.author, size: 24, mobile_classes: "d-none d-sm-inline")
author_output << link_to_member(project, issuable.author, size: 24, by_username: true, avatar: false, mobile_classes: "d-inline d-sm-none")
author_output << issuable_meta_author_slot(issuable.author, css_class: 'ml-1')
-
- if status = user_status(issuable.author)
- author_output << "#{status}".html_safe
- end
+ author_output << issuable_meta_author_status(issuable.author)
author_output
end
@@ -336,42 +322,10 @@ module IssuablesHelper
issuable_path(issuable, close_reopen_params(issuable, :reopen))
end
- def close_reopen_issuable_path(issuable, should_inverse = false)
- 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
- def issuable_url(issuable, *options)
- case issuable
- when Issue
- issue_url(issuable, *options)
- when MergeRequest
- merge_request_url(issuable, *options)
- end
- end
-
- def issuable_button_visibility(issuable, closed)
- return 'hidden' if issuable_button_hidden?(issuable, closed)
- end
-
- def issuable_button_hidden?(issuable, closed)
- case issuable
- when Issue
- issue_button_hidden?(issuable, closed)
- when MergeRequest
- merge_request_button_hidden?(issuable, closed)
- end
- end
-
def issuable_author_is_current_user(issuable)
issuable.author == current_user
end
diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb
index dee009cd3ab..0a9965496b8 100644
--- a/app/helpers/issues_helper.rb
+++ b/app/helpers/issues_helper.rb
@@ -32,14 +32,6 @@ module IssuesHelper
end
end
- def issue_button_visibility(issue, closed)
- return 'hidden' if issue_button_hidden?(issue, closed)
- end
-
- def issue_button_hidden?(issue, closed)
- issue.closed? == closed || (!closed && issue.discussion_locked)
- end
-
def confidential_icon(issue)
sprite_icon('eye-slash', css_class: 'gl-vertical-align-text-bottom') if issue.confidential?
end
diff --git a/app/helpers/markup_helper.rb b/app/helpers/markup_helper.rb
index ed8931fe0f2..25d56ffca2c 100644
--- a/app/helpers/markup_helper.rb
+++ b/app/helpers/markup_helper.rb
@@ -126,16 +126,7 @@ module MarkupHelper
text = wiki_page.content
return '' unless text.present?
- context.merge!(
- pipeline: :wiki,
- project: @project,
- wiki: @wiki,
- repository: @wiki.repository,
- page_slug: wiki_page.slug,
- issuable_state_filter_enabled: true
- )
-
- html = markup_unsafe(wiki_page.path, text, context)
+ html = markup_unsafe(wiki_page.path, text, render_wiki_content_context(@wiki, wiki_page, context))
prepare_for_rendering(html, context)
end
@@ -182,6 +173,20 @@ module MarkupHelper
private
+ def render_wiki_content_context(wiki, wiki_page, context)
+ context.merge(
+ pipeline: :wiki,
+ wiki: wiki,
+ repository: wiki.repository,
+ page_slug: wiki_page.slug,
+ issuable_state_filter_enabled: true
+ ).merge(render_wiki_content_context_container(wiki))
+ end
+
+ def render_wiki_content_context_container(wiki)
+ { project: wiki.container }
+ end
+
# Return +text+, truncated to +max_chars+ characters, excluding any HTML
# tags.
def truncate_visible(text, max_chars)
@@ -311,3 +316,5 @@ module MarkupHelper
extend self
end
+
+MarkupHelper.prepend_if_ee('EE::MarkupHelper')
diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb
index 9cb7edbaeb6..37e701c1c2b 100644
--- a/app/helpers/merge_requests_helper.rb
+++ b/app/helpers/merge_requests_helper.rb
@@ -39,19 +39,6 @@ module MergeRequestsHelper
end
end
- def ci_build_details_path(merge_request)
- build_url = merge_request.source_project.ci_service.build_page(merge_request.diff_head_sha, merge_request.source_branch)
- return unless build_url
-
- parsed_url = URI.parse(build_url)
-
- unless parsed_url.userinfo.blank?
- parsed_url.userinfo = ''
- end
-
- parsed_url.to_s
- end
-
def merge_path_description(merge_request, separator)
if merge_request.for_fork?
"Project:Branches: #{@merge_request.source_project_path}:#{@merge_request.source_branch} #{separator} #{@merge_request.target_project.full_path}:#{@merge_request.target_branch}"
@@ -96,7 +83,7 @@ module MergeRequestsHelper
end
def merge_request_button_hidden?(merge_request, closed)
- merge_request.closed? == closed || (merge_request.merged? == closed && !merge_request.closed?) || merge_request.closed_without_fork?
+ merge_request.closed? == closed || (merge_request.merged? == closed && !merge_request.closed?) || merge_request.closed_or_merged_without_fork?
end
def merge_request_version_path(project, merge_request, merge_request_diff, start_sha = nil)
@@ -166,6 +153,12 @@ module MergeRequestsHelper
current_user.fork_of(project)
end
end
+
+ def toggle_draft_merge_request_path(issuable)
+ wip_event = issuable.work_in_progress? ? 'unwip' : 'wip'
+
+ issuable_path(issuable, { merge_request: { wip_event: wip_event } })
+ end
end
MergeRequestsHelper.prepend_if_ee('EE::MergeRequestsHelper')
diff --git a/app/helpers/notifications_helper.rb b/app/helpers/notifications_helper.rb
index 61fcda6a504..2b68d953431 100644
--- a/app/helpers/notifications_helper.rb
+++ b/app/helpers/notifications_helper.rb
@@ -106,7 +106,8 @@ module NotificationsHelper
when :success_pipeline
s_('NotificationEvent|Successful pipeline')
else
- s_(event.to_s.humanize)
+ event_name = "NotificationEvent|#{event.to_s.humanize}"
+ s_(event_name)
end
end
diff --git a/app/helpers/notify_helper.rb b/app/helpers/notify_helper.rb
index fb68029928c..db7527d9d58 100644
--- a/app/helpers/notify_helper.rb
+++ b/app/helpers/notify_helper.rb
@@ -5,7 +5,7 @@ module NotifyHelper
link_to(entity.to_reference, merge_request_url(entity, *args))
end
- def issue_reference_link(entity, *args)
- link_to(entity.to_reference, issue_url(entity, *args))
+ def issue_reference_link(entity, *args, full: false)
+ link_to(entity.to_reference(full: full), issue_url(entity, *args))
end
end
diff --git a/app/helpers/operations_helper.rb b/app/helpers/operations_helper.rb
index 8105fce10cf..6d721776f0d 100644
--- a/app/helpers/operations_helper.rb
+++ b/app/helpers/operations_helper.rb
@@ -9,24 +9,14 @@ module OperationsHelper
end
end
- def alerts_service
- strong_memoize(:alerts_service) do
- @project.find_or_initialize_service(::AlertsService.to_param)
- end
- end
-
def alerts_settings_data(disabled: false)
{
'prometheus_activated' => prometheus_service.manual_configuration?.to_s,
- 'activated' => alerts_service.activated?.to_s,
'prometheus_form_path' => scoped_integration_path(prometheus_service),
- 'form_path' => scoped_integration_path(alerts_service),
'prometheus_reset_key_path' => reset_alerting_token_project_settings_operations_path(@project),
'prometheus_authorization_key' => @project.alerting_setting&.token,
'prometheus_api_url' => prometheus_service.api_url,
- '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('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/profiles_helper.rb b/app/helpers/profiles_helper.rb
index 04a3b915493..87187e97df4 100644
--- a/app/helpers/profiles_helper.rb
+++ b/app/helpers/profiles_helper.rb
@@ -37,10 +37,4 @@ module ProfilesHelper
def user_status_set_to_busy?(status)
status&.availability == availability_values[:busy]
end
-
- def show_status_emoji?(status)
- return false unless status
-
- status.message.present? || status.emoji != UserStatus::DEFAULT_EMOJI
- end
end
diff --git a/app/helpers/projects/alert_management_helper.rb b/app/helpers/projects/alert_management_helper.rb
index c6ad6bfac01..997551d9659 100644
--- a/app/helpers/projects/alert_management_helper.rb
+++ b/app/helpers/projects/alert_management_helper.rb
@@ -28,7 +28,7 @@ module Projects::AlertManagementHelper
def alert_management_enabled?(project)
!!(
- project.alerts_service_activated? ||
+ project.alert_management_alerts.any? ||
project.prometheus_service_active? ||
AlertManagement::HttpIntegrationsFinder.new(project, active: true).execute.any?
)
diff --git a/app/helpers/projects/terraform_helper.rb b/app/helpers/projects/terraform_helper.rb
index b286bc4d7a5..621d97ffb69 100644
--- a/app/helpers/projects/terraform_helper.rb
+++ b/app/helpers/projects/terraform_helper.rb
@@ -1,10 +1,11 @@
# frozen_string_literal: true
module Projects::TerraformHelper
- def js_terraform_list_data(project)
+ def js_terraform_list_data(current_user, project)
{
empty_state_image: image_path('illustrations/empty-state/empty-serverless-lg.svg'),
- project_path: project.full_path
+ project_path: project.full_path,
+ terraform_admin: current_user&.can?(:admin_terraform_state, project)
}
end
end
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index f25b229d198..80206654cd1 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -463,11 +463,12 @@ module ProjectsHelper
issues: :read_issue,
project_members: :read_project_member,
wiki: :read_wiki,
- feature_flags: :read_feature_flag
+ feature_flags: :read_feature_flag,
+ analytics: :read_analytics
}
end
- def can_view_operations_tab?(current_user, project)
+ def view_operations_tab_ability
[
:metrics_dashboard,
:read_alert_management_alert,
@@ -477,7 +478,13 @@ module ProjectsHelper
:read_cluster,
:read_feature_flag,
:read_terraform_state
- ].any? do |ability|
+ ]
+ end
+
+ def can_view_operations_tab?(current_user, project)
+ return false unless project.feature_available?(:operations, current_user)
+
+ view_operations_tab_ability.any? do |ability|
can?(current_user, ability, project)
end
end
@@ -606,6 +613,7 @@ module ProjectsHelper
def project_permissions_settings(project)
feature = project.project_feature
+
{
packagesEnabled: !!project.packages_enabled,
visibilityLevel: project.visibility_level,
@@ -618,11 +626,14 @@ module ProjectsHelper
wikiAccessLevel: feature.wiki_access_level,
snippetsAccessLevel: feature.snippets_access_level,
pagesAccessLevel: feature.pages_access_level,
+ analyticsAccessLevel: feature.analytics_access_level,
containerRegistryEnabled: !!project.container_registry_enabled,
lfsEnabled: !!project.lfs_enabled,
emailsDisabled: project.emails_disabled?,
metricsDashboardAccessLevel: feature.metrics_dashboard_access_level,
- showDefaultAwardEmojis: project.show_default_award_emojis?
+ operationsAccessLevel: feature.operations_access_level,
+ showDefaultAwardEmojis: project.show_default_award_emojis?,
+ allowEditingCommitMessages: project.allow_editing_commit_messages?
}
end
diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb
index de1e0e4e05e..bdc86043ddc 100644
--- a/app/helpers/search_helper.rb
+++ b/app/helpers/search_helper.rb
@@ -31,7 +31,7 @@ module SearchHelper
[
resources_results,
generic_results
- ].flatten.uniq do |item|
+ ].flatten do |item|
item[:label]
end
end
@@ -370,7 +370,7 @@ module SearchHelper
def highlight_and_truncate_issuable(issuable, search_term, _search_highlight)
return unless issuable.description.present?
- simple_search_highlight_and_truncate(issuable.description, search_term, highlighter: '<span class="gl-text-black-normal gl-font-weight-bold">\1</span>')
+ simple_search_highlight_and_truncate(issuable.description, search_term, highlighter: '<span class="gl-text-gray-900 gl-font-weight-bold">\1</span>')
end
def show_user_search_tab?
diff --git a/app/helpers/services_helper.rb b/app/helpers/services_helper.rb
index 96eb14be4b4..3516000e296 100644
--- a/app/helpers/services_helper.rb
+++ b/app/helpers/services_helper.rb
@@ -75,7 +75,15 @@ module ServicesHelper
end
end
- def integration_form_data(integration)
+ def scoped_reset_integration_path(integration, group: nil)
+ if group.present?
+ reset_group_settings_integration_path(group, integration)
+ else
+ reset_admin_application_settings_integration_path(integration)
+ end
+ end
+
+ def integration_form_data(integration, group: nil)
{
id: integration.id,
show_active: integration.show_active_box?.to_s,
@@ -94,7 +102,7 @@ module ServicesHelper
cancel_path: scoped_integrations_path,
can_test: integration.can_test?.to_s,
test_path: scoped_test_integration_path(integration),
- reset_path: ''
+ reset_path: reset_integration?(integration, group: group) ? scoped_reset_integration_path(integration, group: group) : ''
}
end
@@ -114,14 +122,14 @@ module ServicesHelper
false
end
- def group_level_integrations?
- @group.present? && Feature.enabled?(:group_level_integrations, @group, default_enabled: true)
- end
-
def instance_level_integrations?
!Gitlab.com?
end
+ def reset_integration?(integration, group: nil)
+ integration.persisted? && Feature.enabled?(:reset_integrations, group, type: :development)
+ end
+
extend self
private
diff --git a/app/helpers/sorting_helper.rb b/app/helpers/sorting_helper.rb
index 10174e5d719..38758957dba 100644
--- a/app/helpers/sorting_helper.rb
+++ b/app/helpers/sorting_helper.rb
@@ -1,6 +1,8 @@
# frozen_string_literal: true
module SortingHelper
+ include SortingTitlesValuesHelper
+
def sort_options_hash
{
sort_value_created_date => sort_title_created_date,
@@ -40,6 +42,7 @@ module SortingHelper
sort_value_latest_activity => sort_title_latest_activity,
sort_value_recently_created => sort_title_created_date,
sort_value_name => sort_title_name,
+ sort_value_name_desc => sort_title_name_desc,
sort_value_stars_desc => sort_title_stars
}
@@ -95,8 +98,8 @@ module SortingHelper
sort_value_name_desc => sort_title_name_desc,
sort_value_recently_created => sort_title_recently_created,
sort_value_oldest_created => sort_title_oldest_created,
- sort_value_recently_updated => sort_title_recently_updated,
- sort_value_oldest_updated => sort_title_oldest_updated
+ sort_value_latest_activity => sort_title_recently_updated,
+ sort_value_oldest_activity => sort_title_oldest_updated
}
end
@@ -112,19 +115,6 @@ module SortingHelper
)
end
- def member_sort_options_hash
- {
- sort_value_access_level_asc => sort_title_access_level_asc,
- sort_value_access_level_desc => sort_title_access_level_desc,
- sort_value_last_joined => sort_title_last_joined,
- sort_value_name => sort_title_name_asc,
- sort_value_name_desc => sort_title_name_desc,
- sort_value_oldest_joined => sort_title_oldest_joined,
- sort_value_oldest_signin => sort_title_oldest_signin,
- sort_value_recently_signin => sort_title_recently_signin
- }
- end
-
def milestone_sort_options_hash
{
sort_value_name => sort_title_name_asc,
@@ -186,6 +176,19 @@ module SortingHelper
}
end
+ def member_sort_options_hash
+ {
+ sort_value_access_level_asc => sort_title_access_level_asc,
+ sort_value_access_level_desc => sort_title_access_level_desc,
+ sort_value_last_joined => sort_title_last_joined,
+ sort_value_name => sort_title_name_asc,
+ sort_value_name_desc => sort_title_name_desc,
+ sort_value_oldest_joined => sort_title_oldest_joined,
+ sort_value_oldest_signin => sort_title_oldest_signin,
+ sort_value_recently_signin => sort_title_recently_signin
+ }
+ end
+
def sortable_item(item, path, sorted_by)
link_to item, path, class: sorted_by == item ? 'is-active' : ''
end
@@ -275,340 +278,6 @@ module SortingHelper
sort_direction_button(url, reverse_sort, sort_value)
end
- # Titles.
- def sort_title_access_level_asc
- s_('SortOptions|Access level, ascending')
- end
-
- def sort_title_access_level_desc
- s_('SortOptions|Access level, descending')
- end
-
- def sort_title_created_date
- s_('SortOptions|Created date')
- end
-
- def sort_title_downvotes
- s_('SortOptions|Least popular')
- end
-
- def sort_title_due_date
- s_('SortOptions|Due date')
- end
-
- def sort_title_due_date_later
- s_('SortOptions|Due later')
- end
-
- def sort_title_due_date_soon
- s_('SortOptions|Due soon')
- end
-
- def sort_title_label_priority
- s_('SortOptions|Label priority')
- end
-
- def sort_title_largest_group
- s_('SortOptions|Largest group')
- end
-
- def sort_title_largest_repo
- s_('SortOptions|Largest repository')
- end
-
- def sort_title_last_joined
- s_('SortOptions|Last joined')
- end
-
- def sort_title_latest_activity
- s_('SortOptions|Last updated')
- end
-
- def sort_title_milestone
- s_('SortOptions|Milestone due date')
- end
-
- def sort_title_milestone_later
- s_('SortOptions|Milestone due later')
- end
-
- def sort_title_milestone_soon
- s_('SortOptions|Milestone due soon')
- end
-
- def sort_title_name
- s_('SortOptions|Name')
- end
-
- def sort_title_name_asc
- s_('SortOptions|Name, ascending')
- end
-
- def sort_title_name_desc
- s_('SortOptions|Name, descending')
- end
-
- def sort_title_oldest_activity
- s_('SortOptions|Oldest updated')
- end
-
- def sort_title_oldest_created
- s_('SortOptions|Oldest created')
- end
-
- def sort_title_oldest_joined
- s_('SortOptions|Oldest joined')
- end
-
- def sort_title_oldest_signin
- s_('SortOptions|Oldest sign in')
- end
-
- def sort_title_oldest_starred
- s_('SortOptions|Oldest starred')
- end
-
- def sort_title_oldest_updated
- s_('SortOptions|Oldest updated')
- end
-
- def sort_title_popularity
- s_('SortOptions|Popularity')
- end
-
- def sort_title_priority
- s_('SortOptions|Priority')
- end
-
- def sort_title_recently_created
- s_('SortOptions|Last created')
- end
-
- def sort_title_recently_signin
- s_('SortOptions|Recent sign in')
- end
-
- def sort_title_recently_starred
- s_('SortOptions|Recently starred')
- end
-
- def sort_title_recently_updated
- s_('SortOptions|Last updated')
- end
-
- def sort_title_start_date_later
- s_('SortOptions|Start later')
- end
-
- def sort_title_start_date_soon
- s_('SortOptions|Start soon')
- end
-
- def sort_title_upvotes
- s_('SortOptions|Most popular')
- end
-
- def sort_title_contacted_date
- s_('SortOptions|Last Contact')
- end
-
- def sort_title_most_stars
- s_('SortOptions|Most stars')
- end
-
- def sort_title_stars
- s_('SortOptions|Stars')
- end
-
- def sort_title_oldest_last_activity
- s_('SortOptions|Oldest last activity')
- end
-
- def sort_title_recently_last_activity
- s_('SortOptions|Recent last activity')
- end
-
- def sort_title_relative_position
- s_('SortOptions|Manual')
- end
-
- def sort_title_size
- s_('SortOptions|Size')
- end
-
- def sort_title_expire_date
- s_('SortOptions|Expired date')
- end
-
- def sort_title_relevant
- s_('SortOptions|Relevant')
- end
-
- # Values.
- def sort_value_access_level_asc
- 'access_level_asc'
- end
-
- def sort_value_access_level_desc
- 'access_level_desc'
- end
-
- def sort_value_created_date
- 'created_date'
- end
-
- def sort_value_downvotes
- 'downvotes_desc'
- end
-
- def sort_value_due_date
- 'due_date'
- end
-
- def sort_value_due_date_later
- 'due_date_desc'
- end
-
- def sort_value_due_date_soon
- 'due_date_asc'
- end
-
- def sort_value_label_priority
- 'label_priority'
- end
-
- def sort_value_largest_group
- 'storage_size_desc'
- end
-
- def sort_value_largest_repo
- 'storage_size_desc'
- end
-
- def sort_value_last_joined
- 'last_joined'
- end
-
- def sort_value_latest_activity
- 'latest_activity_desc'
- end
-
- def sort_value_milestone
- 'milestone'
- end
-
- def sort_value_milestone_later
- 'milestone_due_desc'
- end
-
- def sort_value_milestone_soon
- 'milestone_due_asc'
- end
-
- def sort_value_name
- 'name_asc'
- end
-
- def sort_value_name_desc
- 'name_desc'
- end
-
- def sort_value_oldest_activity
- 'latest_activity_asc'
- end
-
- def sort_value_oldest_created
- 'created_asc'
- end
-
- def sort_value_oldest_signin
- 'oldest_sign_in'
- end
-
- def sort_value_oldest_joined
- 'oldest_joined'
- end
-
- def sort_value_oldest_updated
- 'updated_asc'
- end
-
- def sort_value_popularity
- 'popularity'
- end
-
- def sort_value_most_popular
- 'popularity_desc'
- end
-
- def sort_value_least_popular
- 'popularity_asc'
- end
-
- def sort_value_priority
- 'priority'
- end
-
- def sort_value_recently_created
- 'created_desc'
- end
-
- def sort_value_recently_signin
- 'recent_sign_in'
- end
-
- def sort_value_recently_updated
- 'updated_desc'
- end
-
- def sort_value_start_date_later
- 'start_date_desc'
- end
-
- def sort_value_start_date_soon
- 'start_date_asc'
- end
-
- def sort_value_upvotes
- 'upvotes_desc'
- end
-
- def sort_value_contacted_date
- 'contacted_asc'
- end
-
- def sort_value_stars_desc
- 'stars_desc'
- end
-
- def sort_value_stars_asc
- 'stars_asc'
- end
-
- def sort_value_oldest_last_activity
- 'last_activity_on_asc'
- end
-
- def sort_value_recently_last_activity
- 'last_activity_on_desc'
- end
-
- def sort_value_relative_position
- 'relative_position'
- end
-
- def sort_value_size
- 'size_desc'
- end
-
- def sort_value_expire_date
- 'expired_asc'
- end
-
- def sort_value_relevant
- 'relevant'
- end
-
def packages_sort_options_hash
{
sort_value_recently_created => sort_title_created_date,
diff --git a/app/helpers/sorting_titles_values_helper.rb b/app/helpers/sorting_titles_values_helper.rb
new file mode 100644
index 00000000000..27f3638dc73
--- /dev/null
+++ b/app/helpers/sorting_titles_values_helper.rb
@@ -0,0 +1,339 @@
+# frozen_string_literal: true
+
+module SortingTitlesValuesHelper
+ # Titles.
+ def sort_title_access_level_asc
+ s_('SortOptions|Access level, ascending')
+ end
+
+ def sort_title_access_level_desc
+ s_('SortOptions|Access level, descending')
+ end
+
+ def sort_title_created_date
+ s_('SortOptions|Created date')
+ end
+
+ def sort_title_downvotes
+ s_('SortOptions|Least popular')
+ end
+
+ def sort_title_due_date
+ s_('SortOptions|Due date')
+ end
+
+ def sort_title_due_date_later
+ s_('SortOptions|Due later')
+ end
+
+ def sort_title_due_date_soon
+ s_('SortOptions|Due soon')
+ end
+
+ def sort_title_label_priority
+ s_('SortOptions|Label priority')
+ end
+
+ def sort_title_largest_group
+ s_('SortOptions|Largest group')
+ end
+
+ def sort_title_largest_repo
+ s_('SortOptions|Largest repository')
+ end
+
+ def sort_title_last_joined
+ s_('SortOptions|Last joined')
+ end
+
+ def sort_title_latest_activity
+ s_('SortOptions|Last updated')
+ end
+
+ def sort_title_milestone
+ s_('SortOptions|Milestone due date')
+ end
+
+ def sort_title_milestone_later
+ s_('SortOptions|Milestone due later')
+ end
+
+ def sort_title_milestone_soon
+ s_('SortOptions|Milestone due soon')
+ end
+
+ def sort_title_name
+ s_('SortOptions|Name')
+ end
+
+ def sort_title_name_asc
+ s_('SortOptions|Name, ascending')
+ end
+
+ def sort_title_name_desc
+ s_('SortOptions|Name, descending')
+ end
+
+ def sort_title_oldest_activity
+ s_('SortOptions|Oldest updated')
+ end
+
+ def sort_title_oldest_created
+ s_('SortOptions|Oldest created')
+ end
+
+ def sort_title_oldest_joined
+ s_('SortOptions|Oldest joined')
+ end
+
+ def sort_title_oldest_signin
+ s_('SortOptions|Oldest sign in')
+ end
+
+ def sort_title_oldest_starred
+ s_('SortOptions|Oldest starred')
+ end
+
+ def sort_title_oldest_updated
+ s_('SortOptions|Oldest updated')
+ end
+
+ def sort_title_popularity
+ s_('SortOptions|Popularity')
+ end
+
+ def sort_title_priority
+ s_('SortOptions|Priority')
+ end
+
+ def sort_title_recently_created
+ s_('SortOptions|Last created')
+ end
+
+ def sort_title_recently_signin
+ s_('SortOptions|Recent sign in')
+ end
+
+ def sort_title_recently_starred
+ s_('SortOptions|Recently starred')
+ end
+
+ def sort_title_recently_updated
+ s_('SortOptions|Last updated')
+ end
+
+ def sort_title_start_date_later
+ s_('SortOptions|Start later')
+ end
+
+ def sort_title_start_date_soon
+ s_('SortOptions|Start soon')
+ end
+
+ def sort_title_upvotes
+ s_('SortOptions|Most popular')
+ end
+
+ def sort_title_contacted_date
+ s_('SortOptions|Last Contact')
+ end
+
+ def sort_title_most_stars
+ s_('SortOptions|Most stars')
+ end
+
+ def sort_title_stars
+ s_('SortOptions|Stars')
+ end
+
+ def sort_title_oldest_last_activity
+ s_('SortOptions|Oldest last activity')
+ end
+
+ def sort_title_recently_last_activity
+ s_('SortOptions|Recent last activity')
+ end
+
+ def sort_title_relative_position
+ s_('SortOptions|Manual')
+ end
+
+ def sort_title_size
+ s_('SortOptions|Size')
+ end
+
+ def sort_title_expire_date
+ s_('SortOptions|Expired date')
+ end
+
+ def sort_title_relevant
+ s_('SortOptions|Relevant')
+ end
+
+ # Values.
+ def sort_value_access_level_asc
+ 'access_level_asc'
+ end
+
+ def sort_value_access_level_desc
+ 'access_level_desc'
+ end
+
+ def sort_value_created_date
+ 'created_date'
+ end
+
+ def sort_value_downvotes
+ 'downvotes_desc'
+ end
+
+ def sort_value_due_date
+ 'due_date'
+ end
+
+ def sort_value_due_date_later
+ 'due_date_desc'
+ end
+
+ def sort_value_due_date_soon
+ 'due_date_asc'
+ end
+
+ def sort_value_label_priority
+ 'label_priority'
+ end
+
+ def sort_value_largest_group
+ 'storage_size_desc'
+ end
+
+ def sort_value_largest_repo
+ 'storage_size_desc'
+ end
+
+ def sort_value_last_joined
+ 'last_joined'
+ end
+
+ def sort_value_latest_activity
+ 'latest_activity_desc'
+ end
+
+ def sort_value_milestone
+ 'milestone'
+ end
+
+ def sort_value_milestone_later
+ 'milestone_due_desc'
+ end
+
+ def sort_value_milestone_soon
+ 'milestone_due_asc'
+ end
+
+ def sort_value_name
+ 'name_asc'
+ end
+
+ def sort_value_name_desc
+ 'name_desc'
+ end
+
+ def sort_value_oldest_activity
+ 'latest_activity_asc'
+ end
+
+ def sort_value_oldest_created
+ 'created_asc'
+ end
+
+ def sort_value_oldest_signin
+ 'oldest_sign_in'
+ end
+
+ def sort_value_oldest_joined
+ 'oldest_joined'
+ end
+
+ def sort_value_oldest_updated
+ 'updated_asc'
+ end
+
+ def sort_value_popularity
+ 'popularity'
+ end
+
+ def sort_value_most_popular
+ 'popularity_desc'
+ end
+
+ def sort_value_least_popular
+ 'popularity_asc'
+ end
+
+ def sort_value_priority
+ 'priority'
+ end
+
+ def sort_value_recently_created
+ 'created_desc'
+ end
+
+ def sort_value_recently_signin
+ 'recent_sign_in'
+ end
+
+ def sort_value_recently_updated
+ 'updated_desc'
+ end
+
+ def sort_value_start_date_later
+ 'start_date_desc'
+ end
+
+ def sort_value_start_date_soon
+ 'start_date_asc'
+ end
+
+ def sort_value_upvotes
+ 'upvotes_desc'
+ end
+
+ def sort_value_contacted_date
+ 'contacted_asc'
+ end
+
+ def sort_value_stars_desc
+ 'stars_desc'
+ end
+
+ def sort_value_stars_asc
+ 'stars_asc'
+ end
+
+ def sort_value_oldest_last_activity
+ 'last_activity_on_asc'
+ end
+
+ def sort_value_recently_last_activity
+ 'last_activity_on_desc'
+ end
+
+ def sort_value_relative_position
+ 'relative_position'
+ end
+
+ def sort_value_size
+ 'size_desc'
+ end
+
+ def sort_value_expire_date
+ 'expired_asc'
+ end
+
+ def sort_value_relevant
+ 'relevant'
+ end
+end
+
+SortingHelper.include_if_ee('::EE::SortingTitlesValuesHelper')
diff --git a/app/helpers/storage_helper.rb b/app/helpers/storage_helper.rb
index 13bf9c92d52..d6a4d6ac57a 100644
--- a/app/helpers/storage_helper.rb
+++ b/app/helpers/storage_helper.rb
@@ -15,9 +15,11 @@ module StorageHelper
counter_wikis: storage_counter(statistics.wiki_size),
counter_build_artifacts: storage_counter(statistics.build_artifacts_size),
counter_lfs_objects: storage_counter(statistics.lfs_objects_size),
- counter_snippets: storage_counter(statistics.snippets_size)
+ counter_snippets: storage_counter(statistics.snippets_size),
+ counter_packages: storage_counter(statistics.packages_size),
+ counter_uploads: storage_counter(statistics.uploads_size)
}
- _("Repository: %{counter_repositories} / Wikis: %{counter_wikis} / Build Artifacts: %{counter_build_artifacts} / LFS: %{counter_lfs_objects} / Snippets: %{counter_snippets}") % counters
+ _("Repository: %{counter_repositories} / Wikis: %{counter_wikis} / Build Artifacts: %{counter_build_artifacts} / LFS: %{counter_lfs_objects} / Snippets: %{counter_snippets} / Packages: %{counter_packages} / Uploads: %{counter_uploads}") % counters
end
end
diff --git a/app/helpers/suggest_pipeline_helper.rb b/app/helpers/suggest_pipeline_helper.rb
index 3151b792344..f0a12f0e268 100644
--- a/app/helpers/suggest_pipeline_helper.rb
+++ b/app/helpers/suggest_pipeline_helper.rb
@@ -2,8 +2,6 @@
module SuggestPipelineHelper
def should_suggest_gitlab_ci_yml?
- Feature.enabled?(:suggest_pipeline, default_enabled: true) &&
- current_user &&
- params[:suggest_gitlab_ci_yml] == 'true'
+ current_user && params[:suggest_gitlab_ci_yml] == 'true'
end
end
diff --git a/app/helpers/system_note_helper.rb b/app/helpers/system_note_helper.rb
index 79f4810e13a..85e644967ea 100644
--- a/app/helpers/system_note_helper.rb
+++ b/app/helpers/system_note_helper.rb
@@ -38,7 +38,8 @@ module SystemNoteHelper
'status' => 'status',
'alert_issue_added' => 'issues',
'new_alert_added' => 'warning',
- 'severity' => 'information-o'
+ 'severity' => 'information-o',
+ 'cloned' => 'documents'
}.freeze
def system_note_icon_name(note)
diff --git a/app/helpers/time_zone_helper.rb b/app/helpers/time_zone_helper.rb
new file mode 100644
index 00000000000..00f65b72c8e
--- /dev/null
+++ b/app/helpers/time_zone_helper.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+module TimeZoneHelper
+ TIME_ZONE_FORMAT_ATTRS = {
+ short: %i[identifier name offset],
+ full: %i[identifier name abbr offset formatted_offset]
+ }.freeze
+ private_constant :TIME_ZONE_FORMAT_ATTRS
+
+ # format:
+ # * :full - all available fields
+ # * :short (default)
+ #
+ # Example:
+ # timezone_data # :short by default
+ # timezone_data(format: :full)
+ #
+ def timezone_data(format: :short)
+ attrs = TIME_ZONE_FORMAT_ATTRS.fetch(format) do
+ valid_formats = TIME_ZONE_FORMAT_ATTRS.keys.map { |k| ":#{k}"}.join(", ")
+ raise ArgumentError.new("Invalid format :#{format}. Valid formats are #{valid_formats}.")
+ end
+
+ ActiveSupport::TimeZone.all.map do |timezone|
+ {
+ identifier: timezone.tzinfo.identifier,
+ name: timezone.name,
+ abbr: timezone.tzinfo.strftime('%Z'),
+ offset: timezone.now.utc_offset,
+ formatted_offset: timezone.now.formatted_offset
+ }.slice(*attrs)
+ end
+ end
+end
diff --git a/app/helpers/tree_helper.rb b/app/helpers/tree_helper.rb
index 692971f4627..f24aa5d3bcb 100644
--- a/app/helpers/tree_helper.rb
+++ b/app/helpers/tree_helper.rb
@@ -228,12 +228,12 @@ module TreeHelper
gitpod_enabled: !current_user.nil? && current_user.gitpod_enabled,
is_blob: !options[:blob].nil?,
- show_edit_button: show_edit_button?,
+ show_edit_button: show_edit_button?(options),
show_web_ide_button: show_web_ide_button?,
show_gitpod_button: show_gitpod_button?,
web_ide_url: web_ide_url,
- edit_url: edit_url,
+ edit_url: edit_url(options),
gitpod_url: gitpod_url
}
end
diff --git a/app/helpers/user_callouts_helper.rb b/app/helpers/user_callouts_helper.rb
index e93c1b82cd7..a06a31ddf32 100644
--- a/app/helpers/user_callouts_helper.rb
+++ b/app/helpers/user_callouts_helper.rb
@@ -57,7 +57,10 @@ module UserCalloutsHelper
end
def show_registration_enabled_user_callout?
- current_user&.admin? && signup_enabled? && !user_dismissed?(REGISTRATION_ENABLED_CALLOUT)
+ !Gitlab.com? &&
+ current_user&.admin? &&
+ signup_enabled? &&
+ !user_dismissed?(REGISTRATION_ENABLED_CALLOUT)
end
private
diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb
index 7d4ab192f2f..a58f8a6f792 100644
--- a/app/helpers/users_helper.rb
+++ b/app/helpers/users_helper.rb
@@ -1,6 +1,13 @@
# frozen_string_literal: true
module UsersHelper
+ def admin_users_data_attributes(users)
+ {
+ users: Admin::UserSerializer.new.represent(users).to_json,
+ paths: admin_users_paths.to_json
+ }
+ end
+
def user_link(user)
link_to(user.name, user_path(user),
title: user.email,
@@ -60,6 +67,12 @@ module UsersHelper
"access:#{max_project_member_access(project)}"
end
+ def show_status_emoji?(status)
+ return false unless status
+
+ status.message.present? || status.emoji != UserStatus::DEFAULT_EMOJI
+ end
+
def user_status(user)
return unless user
@@ -123,6 +136,19 @@ module UsersHelper
}
end
+ def user_unblock_data(user)
+ {
+ path: unblock_admin_user_path(user),
+ method: 'put',
+ modal_attributes: {
+ title: s_('AdminUsers|Unblock user %{username}?') % { username: sanitize_name(user.name) },
+ message: s_('AdminUsers|You can always block their account again if needed.'),
+ okVariant: 'info',
+ okTitle: s_('AdminUsers|Unblock')
+ }.to_json
+ }
+ end
+
def user_block_effects
header = tag.p s_('AdminUsers|Blocking user has the following effects:')
@@ -136,8 +162,75 @@ module UsersHelper
header + list
end
+ def user_deactivation_data(user, message)
+ {
+ path: deactivate_admin_user_path(user),
+ method: 'put',
+ modal_attributes: {
+ title: s_('AdminUsers|Deactivate user %{username}?') % { username: sanitize_name(user.name) },
+ messageHtml: message,
+ okVariant: 'warning',
+ okTitle: s_('AdminUsers|Deactivate')
+ }.to_json
+ }
+ end
+
+ def user_activation_data(user)
+ {
+ path: activate_admin_user_path(user),
+ method: 'put',
+ modal_attributes: {
+ title: s_('AdminUsers|Activate user %{username}?') % { username: sanitize_name(user.name) },
+ message: s_('AdminUsers|You can always deactivate their account again if needed.'),
+ okVariant: 'info',
+ okTitle: s_('AdminUsers|Activate')
+ }.to_json
+ }
+ end
+
+ def user_deactivation_effects
+ header = tag.p s_('AdminUsers|Deactivating a user has the following effects:')
+
+ list = tag.ul do
+ concat tag.li s_('AdminUsers|The user will be logged out')
+ concat tag.li s_('AdminUsers|The user will not be able to access git repositories')
+ concat tag.li s_('AdminUsers|The user will not be able to access the API')
+ concat tag.li s_('AdminUsers|The user will not receive any notifications')
+ concat tag.li s_('AdminUsers|The user will not be able to use slash commands')
+ concat tag.li s_('AdminUsers|When the user logs back in, their account will reactivate as a fully active account')
+ concat tag.li s_('AdminUsers|Personal projects, group and user history will be left intact')
+ end
+
+ header + list
+ end
+
+ def user_display_name(user)
+ return s_('UserProfile|Blocked user') if user.blocked?
+
+ can_read_profile = can?(current_user, :read_user_profile, user)
+ return s_('UserProfile|Unconfirmed user') unless user.confirmed? || can_read_profile
+
+ user.name
+ end
+
private
+ def admin_users_paths
+ {
+ edit: edit_admin_user_path(:id),
+ approve: approve_admin_user_path(:id),
+ reject: reject_admin_user_path(:id),
+ unblock: unblock_admin_user_path(:id),
+ block: block_admin_user_path(:id),
+ deactivate: deactivate_admin_user_path(:id),
+ activate: activate_admin_user_path(:id),
+ unlock: unlock_admin_user_path(:id),
+ delete: admin_user_path(:id),
+ delete_with_contributions: admin_user_path(:id),
+ admin_user: admin_user_path(:id)
+ }
+ end
+
def blocked_user_badge(user)
pending_approval_badge = { text: s_('AdminUsers|Pending approval'), variant: 'info' }
return pending_approval_badge if user.blocked_pending_approval?
diff --git a/app/helpers/visibility_level_helper.rb b/app/helpers/visibility_level_helper.rb
index 896dcdd2caf..0a37257e124 100644
--- a/app/helpers/visibility_level_helper.rb
+++ b/app/helpers/visibility_level_helper.rb
@@ -157,6 +157,16 @@ module VisibilityLevelHelper
end
end
+ def visibility_level_options(form_model)
+ available_visibility_levels(form_model).map do |level|
+ {
+ level: level,
+ label: visibility_level_label(level),
+ description: visibility_level_description(level, form_model)
+ }
+ end
+ end
+
def snippets_selected_visibility_level(visibility_levels, selected)
visibility_levels.find { |level| level == selected } || visibility_levels.min
end
diff --git a/app/helpers/web_ide_button_helper.rb b/app/helpers/web_ide_button_helper.rb
index 0a4d47eed52..7aa0adc31bd 100644
--- a/app/helpers/web_ide_button_helper.rb
+++ b/app/helpers/web_ide_button_helper.rb
@@ -21,8 +21,8 @@ module WebIdeButtonHelper
can_collaborate? || can_create_mr_from_fork?
end
- def show_edit_button?
- readable_blob? && show_web_ide_button?
+ def show_edit_button?(options = {})
+ readable_blob?(options) && show_web_ide_button?
end
def show_gitpod_button?
@@ -37,8 +37,8 @@ module WebIdeButtonHelper
!project_fork.nil? && !can_push_code?
end
- def readable_blob?
- !readable_blob({}, @path, @project, @ref).nil?
+ def readable_blob?(options = {})
+ !readable_blob(options, @path, @project, @ref).nil?
end
def needs_to_fork?
@@ -49,8 +49,8 @@ module WebIdeButtonHelper
ide_edit_path(project_to_use, @ref, @path || '')
end
- def edit_url
- readable_blob? ? edit_blob_path(@project, @ref, @path || '') : ''
+ def edit_url(options = {})
+ readable_blob?(options) ? edit_blob_path(@project, @ref, @path || '') : ''
end
def gitpod_url
diff --git a/app/helpers/whats_new_helper.rb b/app/helpers/whats_new_helper.rb
index 283d443f51b..bbf5bde5904 100644
--- a/app/helpers/whats_new_helper.rb
+++ b/app/helpers/whats_new_helper.rb
@@ -1,25 +1,19 @@
# frozen_string_literal: true
module WhatsNewHelper
- include Gitlab::WhatsNew
-
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_release_items&.count
- end
+ ReleaseHighlight.most_recent_item_count
end
def whats_new_storage_key
- return unless whats_new_most_recent_version
+ most_recent_version = ReleaseHighlight.versions&.first
- ['display-whats-new-notification', whats_new_most_recent_version].join('-')
- end
+ return unless most_recent_version
- private
+ ['display-whats-new-notification', most_recent_version].join('-')
+ end
- def whats_new_most_recent_version
- Gitlab::ProcessMemoryCache.cache_backend.fetch('whats_new:release_version', expires_in: CACHE_DURATION) do
- whats_new_release_items&.first&.[]('release')
- end
+ def whats_new_versions
+ ReleaseHighlight.versions
end
end