gitlab-org--gitlab-foss/app/helpers/application_helper.rb
Douwe Maan 28e1739a3f Port EE System Header And Footer feature to CE
remove EE specific code
remove EE licence checks
move migration from EE to CE folder structure
move specs from EE to CE folder structure
remove EE specific flag specs
2019-02-21 17:55:51 +02:00

308 lines
8.6 KiB
Ruby

# frozen_string_literal: true
require 'digest/md5'
require 'uri'
module ApplicationHelper
# See https://docs.gitlab.com/ee/development/ee_features.html#code-in-app-views
# rubocop: disable CodeReuse/ActiveRecord
def render_if_exists(partial, locals = {})
render(partial, locals) if partial_exists?(partial)
end
def partial_exists?(partial)
lookup_context.exists?(partial, [], true)
end
def template_exists?(template)
lookup_context.exists?(template, [], false)
end
# rubocop: enable CodeReuse/ActiveRecord
# Check if a particular controller is the current one
#
# args - One or more controller names to check (using path notation when inside namespaces)
#
# Examples
#
# # On TreeController
# current_controller?(:tree) # => true
# current_controller?(:commits) # => false
# current_controller?(:commits, :tree) # => true
#
# # On Admin::ApplicationController
# current_controller?(:application) # => true
# current_controller?('admin/application') # => true
# current_controller?('gitlab/application') # => false
def current_controller?(*args)
args.any? do |v|
v.to_s.downcase == controller.controller_name || v.to_s.downcase == controller.controller_path
end
end
# Check if a particular action is the current one
#
# args - One or more action names to check
#
# Examples
#
# # On Projects#new
# current_action?(:new) # => true
# current_action?(:create) # => false
# current_action?(:new, :create) # => true
def current_action?(*args)
args.any? { |v| v.to_s.downcase == action_name }
end
def last_commit(project)
if project.repo_exists?
time_ago_with_tooltip(project.repository.commit.committed_date)
else
'Never'
end
rescue
'Never'
end
# Define whenever show last push event
# with suggestion to create MR
# rubocop: disable CodeReuse/ActiveRecord
def show_last_push_widget?(event)
# Skip if event is not about added or modified non-master branch
return false unless event && event.last_push_to_non_root? && !event.rm_ref?
project = event.project
# Skip if project repo is empty or MR disabled
return false unless project && !project.empty_repo? && project.feature_available?(:merge_requests, current_user)
# Skip if user already created appropriate MR
return false if project.merge_requests.where(source_branch: event.branch_name).opened.any?
# Skip if user removed branch right after that
return false unless project.repository.branch_exists?(event.branch_name)
true
end
# rubocop: enable CodeReuse/ActiveRecord
def hexdigest(string)
Digest::SHA1.hexdigest string
end
def simple_sanitize(str)
sanitize(str, tags: %w(a span))
end
def body_data_page
[*controller.controller_path.split('/'), controller.action_name].compact.join(':')
end
# shortcut for gitlab config
def gitlab_config
Gitlab.config.gitlab
end
# shortcut for gitlab extra config
def extra_config
Gitlab.config.extra
end
# Render a `time` element with Javascript-based relative date and tooltip
#
# time - Time object
# placement - Tooltip placement String (default: "top")
# html_class - Custom class for `time` element (default: "time_ago")
#
# By default also includes a `script` element with Javascript necessary to
# initialize the `timeago` jQuery extension. If this method is called many
# times, for example rendering hundreds of commits, it's advisable to disable
# this behavior using the `skip_js` argument and re-initializing `timeago`
# manually once all of the elements have been rendered.
#
# A `js-timeago` class is always added to the element, even when a custom
# `html_class` argument is provided.
#
# Returns an HTML-safe String
def time_ago_with_tooltip(time, placement: 'top', html_class: '', short_format: false)
css_classes = [short_format ? 'js-short-timeago' : 'js-timeago']
css_classes << html_class unless html_class.blank?
element = content_tag :time, l(time, format: "%b %d, %Y"),
class: css_classes.join(' '),
title: l(time.to_time.in_time_zone, format: :timeago_tooltip),
datetime: time.to_time.getutc.iso8601,
data: {
toggle: 'tooltip',
placement: placement,
container: 'body'
}
element
end
def edited_time_ago_with_tooltip(object, placement: 'top', html_class: 'time_ago', exclude_author: false)
return unless object.edited?
content_tag :small, class: 'edited-text' do
output = content_tag(:span, 'Edited ')
output << time_ago_with_tooltip(object.last_edited_at, placement: placement, html_class: html_class)
if !exclude_author && object.last_edited_by
output << content_tag(:span, ' by ')
output << link_to_member(object.project, object.last_edited_by, avatar: false, author_class: nil)
end
output
end
end
def promo_host
'about.gitlab.com'
end
def promo_url
'https://' + promo_host
end
def support_url
Gitlab::CurrentSettings.current_application_settings.help_page_support_url.presence || promo_url + '/getting-help/'
end
def page_filter_path(options = {})
without = options.delete(:without)
options = request.query_parameters.merge(options)
if without.present?
without.each do |key|
options.delete(key)
end
end
"#{request.path}?#{options.compact.to_param}"
end
def outdated_browser?
browser.ie? && browser.version.to_i < 10
end
def path_to_key(key, admin = false)
if admin
admin_user_key_path(@user, key)
else
profile_key_path(key)
end
end
def truncate_first_line(message, length = 50)
truncate(message.each_line.first.chomp, length: length) if message
end
# While similarly named to Rails's `link_to_if`, this method behaves quite differently.
# If `condition` is truthy, a link will be returned with the result of the block
# as its body. If `condition` is falsy, only the result of the block will be returned.
def conditional_link_to(condition, options, html_options = {}, &block)
if condition
link_to options, html_options, &block
else
capture(&block)
end
end
def page_class
class_names = []
class_names << 'issue-boards-page' if current_controller?(:boards)
class_names << 'with-performance-bar' if performance_bar_enabled?
class_names << system_message_class
class_names
end
def system_message_class
class_names = []
return class_names unless appearance
class_names << 'with-system-header' if appearance.show_header?
class_names << 'with-system-footer' if appearance.show_footer?
class_names
end
# Returns active css class when condition returns true
# otherwise returns nil.
#
# Example:
# %li{ class: active_when(params[:filter] == '1') }
def active_when(condition)
'active' if condition
end
def show_callout?(name)
cookies[name] != 'true'
end
def linkedin_url(user)
name = user.linkedin
if name =~ %r{\Ahttps?://(www\.)?linkedin\.com/in/}
name
else
"https://www.linkedin.com/in/#{name}"
end
end
def twitter_url(user)
name = user.twitter
if name =~ %r{\Ahttps?://(www\.)?twitter\.com/}
name
else
"https://twitter.com/#{name}"
end
end
def collapsed_sidebar?
cookies["sidebar_collapsed"] == "true"
end
def locale_path
asset_path("locale/#{Gitlab::I18n.locale}/app.js")
end
# Overridden in EE
def read_only_message
return unless Gitlab::Database.read_only?
_('You are on a read-only GitLab instance.')
end
def client_class_list
"gl-browser-#{browser.id} gl-platform-#{browser.platform.id}"
end
def client_js_flags
{
"is#{browser.id.to_s.titlecase}": true,
"is#{browser.platform.id.to_s.titlecase}": true
}
end
def autocomplete_data_sources(object, noteable_type)
return {} unless object && noteable_type
{
members: members_project_autocomplete_sources_path(object, type: noteable_type, type_id: params[:id]),
issues: issues_project_autocomplete_sources_path(object),
mergeRequests: merge_requests_project_autocomplete_sources_path(object),
labels: labels_project_autocomplete_sources_path(object, type: noteable_type, type_id: params[:id]),
milestones: milestones_project_autocomplete_sources_path(object),
commands: commands_project_autocomplete_sources_path(object, type: noteable_type, type_id: params[:id]),
snippets: snippets_project_autocomplete_sources_path(object)
}
end
private
def appearance
::Appearance.current
end
end