2018-08-18 11:19:57 +00:00
# frozen_string_literal: true
2012-09-07 16:57:13 +00:00
module ProjectsHelper
2020-02-15 21:08:49 +00:00
def project_incident_management_setting
@project_incident_management_setting || = @project . incident_management_setting ||
@project . build_incident_management_setting
end
2014-09-25 22:07:40 +00:00
def link_to_project ( project )
2020-09-18 03:09:28 +00:00
link_to namespace_project_path ( namespace_id : project . namespace , id : project ) , title : h ( project . name ) , class : 'gl-link' do
2014-04-11 22:00:58 +00:00
title = content_tag ( :span , project . name , class : 'project-name' )
2012-12-09 08:56:15 +00:00
if project . namespace
2013-10-10 07:53:49 +00:00
namespace = content_tag ( :span , " #{ project . namespace . human_name } / " , class : 'namespace-name' )
2012-12-09 08:56:15 +00:00
title = namespace + title
end
title
end
2012-10-01 13:39:19 +00:00
end
2012-10-29 21:45:11 +00:00
2016-01-29 01:36:48 +00:00
def link_to_member_avatar ( author , opts = { } )
2017-10-20 16:21:44 +00:00
default_opts = { size : 16 , lazy_load : false }
2016-01-29 01:36:48 +00:00
opts = default_opts . merge ( opts )
2017-09-06 16:26:01 +00:00
classes = %W[ avatar avatar-inline s #{ opts [ :size ] } ]
2017-09-05 20:17:53 +00:00
classes << opts [ :avatar_class ] if opts [ :avatar_class ]
2018-02-09 10:43:12 +00:00
avatar = avatar_icon_for_user ( author , opts [ :size ] )
2017-09-14 14:29:26 +00:00
src = opts [ :lazy_load ] ? nil : avatar
image_tag ( src , width : opts [ :size ] , class : classes , alt : '' , " data-src " = > avatar )
2016-01-29 01:36:48 +00:00
end
2017-10-20 16:21:44 +00:00
def author_content_tag ( author , opts = { } )
default_opts = { author_class : 'author' , tooltip : false , by_username : false }
opts = default_opts . merge ( opts )
has_tooltip = ! opts [ :by_username ] && opts [ :tooltip ]
username = opts [ :by_username ] ? author . to_reference : author . name
name_tag_options = { class : [ opts [ :author_class ] ] }
if has_tooltip
name_tag_options [ :title ] = author . to_reference
name_tag_options [ :data ] = { placement : 'top' }
name_tag_options [ :class ] << 'has-tooltip'
end
2018-06-15 08:44:59 +00:00
# NOTE: ActionView::Helpers::TagHelper#content_tag HTML escapes username
content_tag ( :span , username , name_tag_options )
2017-10-20 16:21:44 +00:00
end
2016-03-04 17:37:07 +00:00
def link_to_member ( project , author , opts = { } , & block )
2017-10-20 16:21:44 +00:00
default_opts = { avatar : true , name : true , title : " :name " }
2013-01-17 20:35:45 +00:00
opts = default_opts . merge ( opts )
2018-12-08 03:12:23 +00:00
data_attrs = {
user_id : author . id ,
username : author . username ,
name : author . name
}
2012-12-13 03:14:05 +00:00
return " (deleted) " unless author
2018-08-18 11:19:57 +00:00
author_html = [ ]
2013-01-17 20:35:45 +00:00
2012-12-13 03:14:05 +00:00
# Build avatar image tag
2017-08-31 21:43:13 +00:00
author_html << link_to_member_avatar ( author , opts ) if opts [ :avatar ]
2012-12-13 03:14:05 +00:00
2013-01-11 19:16:37 +00:00
# Build name span tag
2017-10-20 16:21:44 +00:00
author_html << author_content_tag ( author , opts ) if opts [ :name ]
2012-12-13 03:14:05 +00:00
2016-03-04 17:37:07 +00:00
author_html << capture ( & block ) if block
2018-08-18 11:19:57 +00:00
author_html = author_html . join . html_safe
2012-12-13 03:14:05 +00:00
2013-07-24 21:09:56 +00:00
if opts [ :name ]
2018-12-08 03:12:23 +00:00
link_to ( author_html , user_path ( author ) , class : " author-link js-user-link #{ " #{ opts [ :extra_class ] } " if opts [ :extra_class ] } #{ " #{ opts [ :mobile_classes ] } " if opts [ :mobile_classes ] } " , data : data_attrs ) . html_safe
2013-07-24 21:09:56 +00:00
else
2015-12-02 13:18:46 +00:00
title = opts [ :title ] . sub ( " :name " , sanitize ( author . name ) )
2019-09-25 03:06:21 +00:00
link_to ( author_html , user_path ( author ) , class : " author-link has-tooltip " , title : title , data : { container : 'body' , qa_selector : 'assignee_link' } ) . html_safe
2013-07-24 21:09:56 +00:00
end
2012-10-29 21:45:11 +00:00
end
2012-12-12 10:02:29 +00:00
2016-09-01 21:00:43 +00:00
def project_title ( project )
2020-11-12 00:09:44 +00:00
namespace_link = build_namespace_breadcrumb_link ( project )
project_link = build_project_breadcrumb_link ( project )
2015-09-14 17:46:58 +00:00
2017-09-06 11:19:03 +00:00
namespace_link = breadcrumb_list_item ( namespace_link ) unless project . group
project_link = breadcrumb_list_item project_link
2017-08-16 08:14:06 +00:00
2017-09-06 11:19:03 +00:00
" #{ namespace_link } #{ project_link } " . html_safe
2012-12-12 10:02:29 +00:00
end
2013-05-20 11:22:18 +00:00
def remove_project_message ( project )
2020-08-12 21:09:54 +00:00
_ ( " You are going to delete %{project_full_name}. Deleted projects CANNOT be restored! Are you ABSOLUTELY sure? " ) %
2018-03-05 14:15:26 +00:00
{ project_full_name : project . full_name }
2013-05-20 11:22:18 +00:00
end
2013-06-13 19:58:27 +00:00
2014-10-08 10:57:54 +00:00
def transfer_project_message ( project )
2020-09-11 21:08:44 +00:00
_ ( " You are going to transfer %{project_full_name} to another namespace. Are you ABSOLUTELY sure? " ) %
2018-03-05 14:15:26 +00:00
{ project_full_name : project . full_name }
2014-10-08 10:57:54 +00:00
end
2019-11-19 16:17:35 +00:00
def remove_fork_project_description_message ( project )
source = visible_fork_source ( project )
2017-11-03 10:08:36 +00:00
2019-11-19 16:17:35 +00:00
if source
2019-11-27 18:06:30 +00:00
msg = _ ( 'This will remove the fork relationship between this project and %{fork_source}.' ) %
2019-11-19 16:17:35 +00:00
{ fork_source : link_to ( source . full_name , project_path ( source ) ) }
2019-11-27 18:06:30 +00:00
msg . html_safe
2017-11-03 10:08:36 +00:00
else
2019-11-19 16:17:35 +00:00
_ ( 'This will remove the fork relationship between this project and other projects in the fork network.' )
2017-11-03 10:08:36 +00:00
end
2015-10-13 10:24:44 +00:00
end
2019-11-19 16:17:35 +00:00
def remove_fork_project_warning_message ( project )
_ ( " You are going to remove the fork relationship from %{project_full_name}. Are you ABSOLUTELY sure? " ) %
{ project_full_name : project . full_name }
end
def visible_fork_source ( project )
project . fork_source if project . fork_source && can? ( current_user , :read_project , project . fork_source )
end
2013-06-13 19:58:27 +00:00
def project_nav_tabs
@nav_tabs || = get_project_nav_tabs ( @project , current_user )
end
2017-05-29 13:52:02 +00:00
def project_search_tabs? ( tab )
abilities = Array ( search_tab_ability_map [ tab ] )
abilities . any? { | ability | can? ( current_user , ability , @project ) }
end
2013-06-13 19:58:27 +00:00
def project_nav_tab? ( name )
project_nav_tabs . include? name
end
2021-02-04 21:09:06 +00:00
def any_project_nav_tab? ( tabs )
tabs . any? { | tab | project_nav_tab? ( tab ) }
end
2015-04-03 10:22:44 +00:00
def project_for_deploy_key ( deploy_key )
2016-11-16 12:31:08 +00:00
if deploy_key . has_access_to? ( @project )
2015-04-03 10:22:44 +00:00
@project
else
2016-11-17 19:56:35 +00:00
deploy_key . projects . find do | project |
can? ( current_user , :read_project , project )
end
2015-04-03 10:22:44 +00:00
end
end
2015-07-06 12:38:43 +00:00
def can_change_visibility_level? ( project , current_user )
2021-01-12 03:10:47 +00:00
can? ( current_user , :change_visibility_level , project )
2015-07-06 12:38:43 +00:00
end
2019-08-17 05:56:48 +00:00
def can_disable_emails? ( project , current_user )
return false if project . group & . emails_disabled?
2019-10-03 21:07:29 +00:00
can? ( current_user , :set_emails_disabled , project )
2019-08-17 05:56:48 +00:00
end
2016-08-24 11:13:26 +00:00
def last_push_event
2017-09-01 10:50:14 +00:00
current_user & . recent_push ( @project )
2016-08-24 11:13:26 +00:00
end
2017-02-06 16:59:54 +00:00
def link_to_autodeploy_doc
2020-07-08 18:09:05 +00:00
link_to _ ( 'About auto deploy' ) , help_page_path ( 'topics/autodevops/stages.md' , anchor : 'auto-deploy' ) , target : '_blank'
2017-02-06 16:59:54 +00:00
end
2017-02-07 15:59:38 +00:00
def autodeploy_flash_notice ( branch_name )
2020-08-17 12:10:12 +00:00
html_escape ( _ ( " Branch %{branch_name} was created. To set up auto deploy, choose a GitLab CI Yaml template and commit your changes. %{link_to_autodeploy_doc} " ) ) %
{ branch_name : tag . strong ( truncate ( sanitize ( branch_name ) ) ) , link_to_autodeploy_doc : link_to_autodeploy_doc }
2017-02-07 15:59:38 +00:00
end
2019-03-19 19:56:03 +00:00
def project_list_cache_key ( project , pipeline_status : true )
2017-05-12 10:33:26 +00:00
key = [
2017-05-12 15:26:01 +00:00
project . route . cache_key ,
2017-05-12 10:33:26 +00:00
project . cache_key ,
2018-06-13 16:57:18 +00:00
project . last_activity_date ,
2017-05-12 10:33:26 +00:00
controller . controller_name ,
controller . action_name ,
2018-02-02 18:39:55 +00:00
Gitlab :: CurrentSettings . cache_key ,
2017-12-11 14:21:06 +00:00
" cross-project: #{ can? ( current_user , :read_cross_project ) } " ,
2018-07-06 07:51:31 +00:00
max_project_member_access_cache_key ( project ) ,
2019-03-19 19:56:03 +00:00
pipeline_status ,
2019-11-19 12:06:00 +00:00
Gitlab :: I18n . locale ,
2018-06-14 08:59:24 +00:00
'v2.6'
2017-05-12 10:33:26 +00:00
]
2019-03-19 19:56:03 +00:00
key << pipeline_status_cache_key ( project . pipeline_status ) if pipeline_status && project . pipeline_status . has_status?
2017-03-16 09:53:48 +00:00
key
end
2017-04-26 12:04:22 +00:00
def load_pipeline_status ( projects )
2017-06-21 13:48:12 +00:00
Gitlab :: Cache :: Ci :: ProjectPipelineStatus
. load_in_batch_for_projects ( projects )
2017-04-26 12:04:22 +00:00
end
2017-06-12 16:13:22 +00:00
def show_no_ssh_key_message?
2018-08-03 20:52:01 +00:00
Gitlab :: CurrentSettings . user_show_add_ssh_key_message? &&
cookies [ :hide_no_ssh_message ] . blank? &&
! current_user . hide_no_ssh_key &&
current_user . require_ssh_key?
2017-06-12 16:13:22 +00:00
end
def show_no_password_message?
cookies [ :hide_no_password_message ] . blank? && ! current_user . hide_no_password &&
2017-11-23 13:16:14 +00:00
current_user . require_extra_setup_for_git_auth?
2017-06-12 16:13:22 +00:00
end
2018-12-28 22:58:22 +00:00
def show_auto_devops_implicitly_enabled_banner? ( project , user )
return false unless user_can_see_auto_devops_implicitly_enabled_banner? ( project , user )
2018-09-04 15:23:11 +00:00
2018-12-28 22:58:22 +00:00
cookies [ " hide_auto_devops_implicitly_enabled_banner_ #{ project . id } " . to_sym ] . blank?
2018-09-04 15:23:11 +00:00
end
2017-06-12 16:13:22 +00:00
def link_to_set_password
2017-11-23 13:16:14 +00:00
if current_user . require_password_creation_for_git?
2017-06-12 16:13:22 +00:00
link_to s_ ( 'SetPasswordToCloneLink|set a password' ) , edit_profile_password_path
else
link_to s_ ( 'CreateTokenToCloneLink|create a personal access token' ) , profile_personal_access_tokens_path
end
end
2017-08-04 13:40:33 +00:00
# Returns true if any projects are present.
#
# If the relation has a LIMIT applied we'll cast the relation to an Array
# since repeated any? checks would otherwise result in multiple COUNT queries
# being executed.
#
# If no limit is applied we'll just issue a COUNT since the result set could
# be too large to load into memory.
def any_projects? ( projects )
2017-08-15 10:33:07 +00:00
return projects . any? if projects . is_a? ( Array )
2017-08-04 13:40:33 +00:00
if projects . limit_value
projects . to_a . any?
else
projects . except ( :offset ) . any?
end
end
2019-04-19 08:36:16 +00:00
# TODO: Remove this method when removing the feature flag
2019-09-18 14:02:45 +00:00
# https://gitlab.com/gitlab-org/gitlab/merge_requests/11209#note_162234863
2019-06-05 00:10:24 +00:00
# make sure to remove from the EE specific controller as well: ee/app/controllers/ee/dashboard/projects_controller.rb
2017-09-21 10:03:14 +00:00
def show_projects? ( projects , params )
2019-04-19 08:36:16 +00:00
Feature . enabled? ( :project_list_filter_bar ) || ! ! ( params [ :personal ] || params [ :name ] || any_projects? ( projects ) )
2017-08-04 13:40:33 +00:00
end
2018-02-23 09:00:19 +00:00
def push_to_create_project_command ( user = current_user )
repository_url =
if Gitlab :: CurrentSettings . current_application_settings . enabled_git_access_protocol == 'http'
user_url ( user )
else
Gitlab . config . gitlab_shell . ssh_path_prefix + user . username
end
" git push --set-upstream #{ repository_url } /$(git rev-parse --show-toplevel | xargs basename).git $(git rev-parse --abbrev-ref HEAD) "
end
2018-06-05 10:10:34 +00:00
def show_xcode_link? ( project = @project )
browser . platform . mac? && project . repository . xcode_project?
end
def xcode_uri_to_repo ( project = @project )
" xcode://clone?repo= #{ CGI . escape ( default_url_to_repo ( project ) ) } "
end
2018-12-19 19:37:08 +00:00
def explore_projects_tab?
current_page? ( explore_projects_path ) ||
current_page? ( trending_explore_projects_path ) ||
current_page? ( starred_explore_projects_path )
end
def show_merge_request_count? ( disabled : false , compact_mode : false )
2020-05-13 21:08:55 +00:00
! disabled && ! compact_mode
2018-12-19 19:37:08 +00:00
end
def show_issue_count? ( disabled : false , compact_mode : false )
2020-05-13 21:08:55 +00:00
! disabled && ! compact_mode
2018-12-19 19:37:08 +00:00
end
2019-01-06 12:59:10 +00:00
def settings_operations_available?
2020-11-06 18:09:07 +00:00
! @project . archived? && can? ( current_user , :admin_operations , @project )
2019-01-06 12:59:10 +00:00
end
2019-03-01 14:51:54 +00:00
def error_tracking_setting_project_json
setting = @project . error_tracking_setting
return if setting . blank? || setting . project_slug . blank? ||
setting . organization_slug . blank?
{
name : setting . project_name ,
organization_name : setting . organization_name ,
organization_slug : setting . organization_slug ,
slug : setting . project_slug
} . to_json
end
2019-04-11 14:03:02 +00:00
def directory?
@path . present?
end
2019-04-09 15:38:58 +00:00
def external_classification_label_help_message
default_label = :: Gitlab :: CurrentSettings . current_application_settings
. external_authorization_service_default_label
s_ (
" ExternalAuthorizationService|When no classification label is set the " \
" default label `%{default_label}` will be used. "
) % { default_label : default_label }
end
2019-05-10 22:00:36 +00:00
def can_import_members?
Ability . allowed? ( current_user , :admin_project_member , @project )
end
2019-05-21 17:50:06 +00:00
def project_can_be_shared?
! membership_locked? || @project . allowed_to_share_with_group?
end
def membership_locked?
false
end
def share_project_description ( project )
share_with_group = project . allowed_to_share_with_group?
share_with_members = ! membership_locked?
description =
if share_with_group && share_with_members
2020-08-17 12:10:12 +00:00
_ ( " You can invite a new member to %{project_name} or invite another group. " )
2019-05-21 17:50:06 +00:00
elsif share_with_group
2020-08-17 12:10:12 +00:00
_ ( " You can invite another group to %{project_name}. " )
2019-05-21 17:50:06 +00:00
elsif share_with_members
2020-08-17 12:10:12 +00:00
_ ( " You can invite a new member to %{project_name}. " )
2019-05-21 17:50:06 +00:00
end
2020-08-17 12:10:12 +00:00
html_escape ( description ) % { project_name : tag . strong ( project . name ) }
2019-05-21 17:50:06 +00:00
end
2019-05-29 13:36:36 +00:00
def metrics_external_dashboard_url
@project . metrics_setting_external_dashboard_url
end
2020-06-09 03:08:27 +00:00
def metrics_dashboard_timezone
@project . metrics_setting_dashboard_timezone
end
2019-10-03 21:07:29 +00:00
def grafana_integration_url
@project . grafana_integration & . grafana_url
end
2020-01-30 21:08:47 +00:00
def grafana_integration_masked_token
@project . grafana_integration & . masked_token
2019-10-03 21:07:29 +00:00
end
2019-11-01 18:06:00 +00:00
def grafana_integration_enabled?
@project . grafana_integration & . enabled?
end
2020-02-20 21:08:48 +00:00
def project_license_name ( project )
2020-06-24 18:09:03 +00:00
key = " project: #{ project . id } :license_name "
Gitlab :: SafeRequestStore . fetch ( key ) { project . repository . license & . name }
2020-02-20 21:08:48 +00:00
rescue GRPC :: Unavailable , GRPC :: DeadlineExceeded , Gitlab :: Git :: CommandError = > e
Gitlab :: ErrorTracking . track_exception ( e )
2020-06-24 18:09:03 +00:00
Gitlab :: SafeRequestStore [ key ] = nil
2020-02-20 21:08:48 +00:00
nil
end
2013-06-13 19:58:27 +00:00
private
2021-02-04 21:09:06 +00:00
def can_read_security_configuration? ( project , current_user )
2021-03-13 00:09:16 +00:00
can? ( current_user , :access_security_and_compliance , project ) &&
can? ( current_user , :read_security_configuration , project )
2021-02-18 18:10:41 +00:00
end
2021-02-04 21:09:06 +00:00
def get_project_security_nav_tabs ( project , current_user )
if can_read_security_configuration? ( project , current_user )
[ :security_and_compliance , :security_configuration ]
else
[ ]
end
end
# rubocop:disable Metrics/CyclomaticComplexity
2013-06-13 19:58:27 +00:00
def get_project_nav_tabs ( project , current_user )
2016-05-03 12:58:50 +00:00
nav_tabs = [ :home ]
2013-06-13 19:58:27 +00:00
2019-05-03 13:29:20 +00:00
unless project . empty_repo?
2020-07-14 12:09:14 +00:00
nav_tabs += [ :files , :commits , :network , :graphs , :forks ] if can? ( current_user , :download_code , project )
2019-05-03 13:29:20 +00:00
nav_tabs << :releases if can? ( current_user , :read_release , project )
2013-06-13 19:58:27 +00:00
end
2021-02-04 21:09:06 +00:00
nav_tabs += get_project_security_nav_tabs ( project , current_user )
2015-05-25 14:42:41 +00:00
if project . repo_exists? && can? ( current_user , :read_merge_request , project )
2013-06-13 19:58:27 +00:00
nav_tabs << :merge_requests
end
2016-05-18 17:28:48 +00:00
if Gitlab . config . registry . enabled && can? ( current_user , :read_container_image , project )
2016-05-09 19:34:10 +00:00
nav_tabs << :container_registry
2016-04-18 12:14:40 +00:00
end
2021-04-01 12:08:56 +00:00
if Feature . enabled? ( :infrastructure_registry_page )
nav_tabs << :infrastructure_registry
end
2019-01-28 12:12:30 +00:00
# Pipelines feature is tied to presence of builds
if can? ( current_user , :read_build , project )
2017-05-05 18:16:54 +00:00
nav_tabs << :pipelines
2018-05-29 11:37:59 +00:00
end
2020-05-21 18:08:27 +00:00
if can_view_operations_tab? ( current_user , project )
2018-05-16 11:16:33 +00:00
nav_tabs << :operations
2017-05-05 18:16:54 +00:00
end
2020-07-27 09:09:42 +00:00
if can_view_product_analytics? ( current_user , project )
nav_tabs << :product_analytics
end
2017-05-29 13:52:02 +00:00
tab_ability_map . each do | tab , ability |
if can? ( current_user , ability , project )
nav_tabs << tab
end
end
2020-07-14 12:09:14 +00:00
apply_external_nav_tabs ( nav_tabs , project )
2019-01-09 15:05:52 +00:00
2020-07-21 12:09:30 +00:00
nav_tabs += package_nav_tabs ( project , current_user )
2021-02-16 09:09:36 +00:00
nav_tabs << :learn_gitlab if learn_gitlab_experiment_enabled? ( project )
2020-07-14 12:09:14 +00:00
nav_tabs
2017-05-29 13:52:02 +00:00
end
2021-02-04 21:09:06 +00:00
# rubocop:enable Metrics/CyclomaticComplexity
2017-05-29 13:52:02 +00:00
2020-07-21 12:09:30 +00:00
def package_nav_tabs ( project , current_user )
[ ] . tap do | tabs |
if :: Gitlab . config . packages . enabled && can? ( current_user , :read_package , project )
tabs << :packages
end
end
end
2020-07-14 12:09:14 +00:00
def apply_external_nav_tabs ( nav_tabs , project )
nav_tabs << :external_issue_tracker if project . external_issue_tracker
nav_tabs << :external_wiki if project . external_wiki
if project . has_confluence?
nav_tabs . delete ( :wiki )
nav_tabs << :confluence
2019-01-09 15:05:52 +00:00
end
end
2017-05-29 13:52:02 +00:00
def tab_ability_map
{
2020-07-14 12:09:14 +00:00
cycle_analytics : :read_cycle_analytics ,
2020-05-21 18:08:27 +00:00
environments : :read_environment ,
metrics_dashboards : :metrics_dashboard ,
milestones : :read_milestone ,
snippets : :read_snippet ,
settings : :admin_project ,
builds : :read_build ,
clusters : :read_cluster ,
serverless : :read_cluster ,
2020-11-06 12:09:17 +00:00
terraform : :read_terraform_state ,
2020-05-21 18:08:27 +00:00
error_tracking : :read_sentry_issue ,
alert_management : :read_alert_management_alert ,
2020-09-30 21:10:09 +00:00
incidents : :read_issue ,
2020-05-21 18:08:27 +00:00
labels : :read_label ,
issues : :read_issue ,
project_members : :read_project_member ,
2020-10-13 15:08:53 +00:00
wiki : :read_wiki ,
2020-12-16 21:09:57 +00:00
feature_flags : :read_feature_flag ,
analytics : :read_analytics
2016-12-21 18:36:24 +00:00
}
2017-05-29 13:52:02 +00:00
end
2016-12-21 18:36:24 +00:00
2020-12-02 00:09:45 +00:00
def view_operations_tab_ability
2020-09-30 21:10:09 +00:00
[
:metrics_dashboard ,
:read_alert_management_alert ,
:read_environment ,
:read_issue ,
:read_sentry_issue ,
2020-10-13 15:08:53 +00:00
:read_cluster ,
2020-11-06 12:09:17 +00:00
:read_feature_flag ,
:read_terraform_state
2020-12-02 00:09:45 +00:00
]
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 |
2020-05-21 18:08:27 +00:00
can? ( current_user , ability , project )
end
end
2020-07-27 09:09:42 +00:00
def can_view_product_analytics? ( current_user , project )
Feature . enabled? ( :product_analytics , project ) &&
can? ( current_user , :read_product_analytics , project )
end
2017-05-29 13:52:02 +00:00
def search_tab_ability_map
@search_tab_ability_map || = tab_ability_map . merge (
blobs : :download_code ,
commits : :download_code ,
merge_requests : :read_merge_request ,
2020-01-23 12:08:38 +00:00
notes : [ :read_merge_request , :download_code , :read_issue , :read_snippet ] ,
2021-02-12 09:08:48 +00:00
members : :read_project_member
2017-05-29 13:52:02 +00:00
)
2013-06-13 19:58:27 +00:00
end
2013-09-24 19:14:28 +00:00
2016-08-24 22:08:23 +00:00
def project_lfs_status ( project )
if project . lfs_enabled?
2016-08-30 22:17:45 +00:00
content_tag ( :span , class : 'lfs-enabled' ) do
2017-06-07 20:13:44 +00:00
s_ ( 'LFSStatus|Enabled' )
2016-08-24 22:08:23 +00:00
end
else
2016-08-30 22:17:45 +00:00
content_tag ( :span , class : 'lfs-disabled' ) do
2017-06-07 20:13:44 +00:00
s_ ( 'LFSStatus|Disabled' )
2016-08-24 22:08:23 +00:00
end
end
end
2013-09-24 19:14:28 +00:00
def git_user_name
if current_user
2017-09-13 12:39:50 +00:00
current_user . name . gsub ( '"' , '\"' )
2013-09-24 19:14:28 +00:00
else
2017-06-07 20:13:44 +00:00
_ ( " Your name " )
2013-09-24 19:14:28 +00:00
end
end
def git_user_email
if current_user
2019-08-29 18:56:22 +00:00
current_user . commit_email
2013-09-24 19:14:28 +00:00
else
" your@email.com "
end
end
2013-10-10 08:05:49 +00:00
2015-11-25 00:32:06 +00:00
def default_url_to_repo ( project = @project )
2016-05-04 21:05:16 +00:00
case default_clone_protocol
when 'ssh'
2015-12-06 19:48:04 +00:00
project . ssh_url_to_repo
else
2017-05-30 12:11:58 +00:00
project . http_url_to_repo
2015-12-06 19:48:04 +00:00
end
2013-12-04 02:13:19 +00:00
end
2013-12-27 10:13:30 +00:00
2018-09-06 07:27:39 +00:00
def default_clone_label
_ ( " Copy %{protocol} clone URL " ) % { protocol : default_clone_protocol . upcase }
end
2013-12-04 02:13:19 +00:00
def default_clone_protocol
2016-06-15 22:30:55 +00:00
if allowed_protocols_present?
enabled_protocol
2015-12-06 19:48:04 +00:00
else
2018-06-20 16:38:42 +00:00
extra_default_clone_protocol
end
end
def extra_default_clone_protocol
if ! current_user || current_user . require_ssh_key?
gitlab_config . protocol
else
'ssh'
2015-12-06 19:48:04 +00:00
end
2013-12-04 02:13:19 +00:00
end
2013-12-29 11:55:45 +00:00
2018-12-07 13:20:05 +00:00
def sidebar_operations_link_path ( project = @project )
2020-10-13 15:08:53 +00:00
if can? ( current_user , :read_environment , project )
metrics_project_environments_path ( project )
else
project_feature_flags_path ( project )
end
2018-12-07 13:20:05 +00:00
end
2013-12-29 11:55:45 +00:00
def project_last_activity ( project )
if project . last_activity_at
2015-06-17 18:04:14 +00:00
time_ago_with_tooltip ( project . last_activity_at , placement : 'bottom' , html_class : 'last_activity_time_ago' )
2013-12-29 11:55:45 +00:00
else
2017-06-07 20:13:44 +00:00
s_ ( " ProjectLastActivity|Never " )
2013-12-29 11:55:45 +00:00
end
end
2014-07-15 12:34:06 +00:00
2014-12-31 13:07:48 +00:00
def project_status_css_class ( status )
case status
when " started "
2018-06-06 01:09:58 +00:00
" table-active "
2014-12-31 13:07:48 +00:00
when " failed "
2018-06-06 01:09:58 +00:00
" table-danger "
2014-12-31 13:07:48 +00:00
when " finished "
2018-06-06 01:09:58 +00:00
" table-success "
2014-12-31 13:07:48 +00:00
end
end
2016-12-08 16:28:49 +00:00
2015-07-09 12:47:28 +00:00
def readme_cache_key
2015-07-24 06:52:21 +00:00
sha = @project . commit . try ( :sha ) || 'nil'
2017-07-20 09:34:09 +00:00
[ @project . full_path , sha , " readme " ] . join ( '-' )
2015-07-09 12:47:28 +00:00
end
2015-07-17 13:22:56 +00:00
2015-09-14 18:23:01 +00:00
def current_ref
@ref || @repository . try ( :root_ref )
end
2015-09-14 17:46:58 +00:00
2016-09-16 19:15:39 +00:00
def project_child_container_class ( view_path )
2020-06-26 06:09:03 +00:00
view_path == " projects/issues/issues " ? " gl-mt-3 " : " project-show- #{ view_path } "
2016-09-16 19:15:39 +00:00
end
2016-11-05 17:28:29 +00:00
def project_issues ( project )
IssuesFinder . new ( current_user , project_id : project . id ) . execute
end
2016-11-22 17:16:30 +00:00
2017-04-17 13:57:09 +00:00
def restricted_levels
return [ ] if current_user . admin?
2018-02-02 18:39:55 +00:00
Gitlab :: CurrentSettings . restricted_visibility_levels || [ ]
2016-11-22 17:16:30 +00:00
end
2017-07-13 14:23:55 +00:00
2017-09-07 18:07:40 +00:00
def project_permissions_settings ( project )
feature = project . project_feature
2020-12-10 15:10:12 +00:00
2017-09-07 18:07:40 +00:00
{
2020-07-21 12:09:30 +00:00
packagesEnabled : ! ! project . packages_enabled ,
2017-09-07 18:07:40 +00:00
visibilityLevel : project . visibility_level ,
requestAccessEnabled : ! ! project . request_access_enabled ,
issuesAccessLevel : feature . issues_access_level ,
repositoryAccessLevel : feature . repository_access_level ,
2020-01-17 18:08:41 +00:00
forkingAccessLevel : feature . forking_access_level ,
2017-09-07 18:07:40 +00:00
mergeRequestsAccessLevel : feature . merge_requests_access_level ,
buildsAccessLevel : feature . builds_access_level ,
wikiAccessLevel : feature . wiki_access_level ,
snippetsAccessLevel : feature . snippets_access_level ,
2018-10-05 13:41:11 +00:00
pagesAccessLevel : feature . pages_access_level ,
2020-12-16 21:09:57 +00:00
analyticsAccessLevel : feature . analytics_access_level ,
2017-09-07 18:07:40 +00:00
containerRegistryEnabled : ! ! project . container_registry_enabled ,
2019-08-17 05:56:48 +00:00
lfsEnabled : ! ! project . lfs_enabled ,
2020-04-30 09:09:39 +00:00
emailsDisabled : project . emails_disabled? ,
2020-05-15 15:08:04 +00:00
metricsDashboardAccessLevel : feature . metrics_dashboard_access_level ,
2020-11-27 12:09:14 +00:00
operationsAccessLevel : feature . operations_access_level ,
2020-12-10 15:10:12 +00:00
showDefaultAwardEmojis : project . show_default_award_emojis? ,
2021-02-18 18:10:41 +00:00
allowEditingCommitMessages : project . allow_editing_commit_messages? ,
securityAndComplianceAccessLevel : project . security_and_compliance_access_level
2017-09-07 18:07:40 +00:00
}
end
def project_permissions_panel_data ( project )
2018-08-24 08:37:06 +00:00
{
2020-07-21 12:09:30 +00:00
packagesAvailable : :: Gitlab . config . packages . enabled ,
packagesHelpPath : help_page_path ( 'user/packages/index' ) ,
2017-09-07 18:07:40 +00:00
currentSettings : project_permissions_settings ( project ) ,
2019-08-17 05:56:48 +00:00
canDisableEmails : can_disable_emails? ( project , current_user ) ,
2017-09-07 18:07:40 +00:00
canChangeVisibilityLevel : can_change_visibility_level? ( project , current_user ) ,
allowedVisibilityOptions : project_allowed_visibility_levels ( project ) ,
visibilityHelpPath : help_page_path ( 'public_access/public_access' ) ,
registryAvailable : Gitlab . config . registry . enabled ,
2019-09-17 12:06:48 +00:00
registryHelpPath : help_page_path ( 'user/packages/container_registry/index' ) ,
2018-04-24 10:51:39 +00:00
lfsAvailable : Gitlab . config . lfs . enabled ,
2020-04-01 18:07:56 +00:00
lfsHelpPath : help_page_path ( 'topics/git/lfs/index' ) ,
2020-03-25 00:08:11 +00:00
lfsObjectsExist : project . lfs_objects . exists? ,
2020-04-01 18:07:56 +00:00
lfsObjectsRemovalHelpPath : help_page_path ( 'topics/git/lfs/index' , anchor : 'removing-objects-from-lfs' ) ,
2018-10-05 13:41:11 +00:00
pagesAvailable : Gitlab . config . pages . enabled ,
pagesAccessControlEnabled : Gitlab . config . pages . access_control ,
2020-01-14 18:08:31 +00:00
pagesAccessControlForced : :: Gitlab :: Pages . access_control_is_forced? ,
2021-03-13 00:09:16 +00:00
pagesHelpPath : help_page_path ( 'user/project/pages/introduction' , anchor : 'gitlab-pages-access-control' )
2017-09-07 18:07:40 +00:00
}
2018-08-24 08:37:06 +00:00
end
2017-09-07 18:07:40 +00:00
2018-08-24 08:37:06 +00:00
def project_permissions_panel_data_json ( project )
project_permissions_panel_data ( project ) . to_json . html_safe
2017-09-07 18:07:40 +00:00
end
def project_allowed_visibility_levels ( project )
Gitlab :: VisibilityLevel . values . select do | level |
project . visibility_level_allowed? ( level ) && ! restricted_levels . include? ( level )
end
end
2017-07-13 14:23:55 +00:00
def find_file_path
return unless @project && ! @project . empty_repo?
2020-04-30 21:09:47 +00:00
return unless can? ( current_user , :download_code , @project )
2017-07-13 14:23:55 +00:00
ref = @ref || @project . repository . root_ref
project_find_file_path ( @project , ref )
end
2017-12-11 14:21:06 +00:00
def can_show_last_commit_in_list? ( project )
can? ( current_user , :read_cross_project ) && project . commit
end
2018-01-03 08:07:03 +00:00
def pages_https_only_disabled?
! @project . pages_domains . all? ( & :https? )
end
def pages_https_only_title
return unless pages_https_only_disabled?
" You must enable HTTPS for all your domains first "
end
def pages_https_only_label_class
if pages_https_only_disabled?
" list-label disabled "
else
" list-label "
end
end
2018-06-20 16:38:42 +00:00
2019-01-28 17:51:49 +00:00
def filter_starrer_path ( options = { } )
options = params . slice ( :sort ) . merge ( options ) . permit!
" #{ request . path } ? #{ options . to_param } "
end
2021-02-04 21:09:06 +00:00
def sidebar_security_configuration_paths
%w[
projects / security / configuration #show
]
end
2018-06-20 16:38:42 +00:00
def sidebar_settings_paths
%w[
projects #edit
integrations #show
services #edit
2020-02-24 18:09:05 +00:00
hooks #index
hooks #edit
2020-05-15 09:07:59 +00:00
access_tokens #index
2020-02-24 18:09:05 +00:00
hook_logs #show
2018-06-20 16:38:42 +00:00
repository #show
ci_cd #show
2018-12-13 15:55:43 +00:00
operations #show
2018-06-20 16:38:42 +00:00
badges #index
pages #show
]
end
2018-11-08 07:02:44 +00:00
def sidebar_operations_paths
%w[
environments
clusters
2018-12-06 18:08:49 +00:00
functions
2019-01-11 22:52:26 +00:00
error_tracking
2020-04-21 15:21:10 +00:00
alert_management
2020-07-23 09:09:18 +00:00
incidents
incident_management
2018-11-08 07:02:44 +00:00
user
gcp
2019-12-16 18:08:22 +00:00
logs
2020-07-27 09:09:42 +00:00
product_analytics
2020-08-13 03:10:13 +00:00
metrics_dashboard
2020-10-13 15:08:53 +00:00
feature_flags
2020-10-09 00:08:41 +00:00
tracings
2020-11-06 12:09:17 +00:00
terraform
2018-11-08 07:02:44 +00:00
]
end
2018-12-28 22:58:22 +00:00
2021-02-04 21:09:06 +00:00
def sidebar_security_paths
%w[ projects/security/configuration # show ]
end
2018-12-28 22:58:22 +00:00
def user_can_see_auto_devops_implicitly_enabled_banner? ( project , user )
Ability . allowed? ( user , :admin_project , project ) &&
project . has_auto_devops_implicitly_enabled? &&
project . builds_enabled? &&
! project . repository . gitlab_ci_yml
end
2019-05-29 09:24:35 +00:00
2019-12-06 12:06:21 +00:00
def show_visibility_confirm_modal? ( project )
project . unlink_forks_upon_visibility_decrease_enabled? && project . visibility_level > Gitlab :: VisibilityLevel :: PRIVATE && project . forks_count > 0
end
2020-01-24 15:09:00 +00:00
def settings_container_registry_expiration_policy_available? ( project )
2020-02-17 12:09:20 +00:00
Gitlab . config . registry . enabled &&
2020-02-13 15:08:52 +00:00
can? ( current_user , :destroy_container_image , project )
2020-01-24 15:09:00 +00:00
end
2020-05-05 21:09:42 +00:00
2020-11-12 00:09:44 +00:00
def build_project_breadcrumb_link ( project )
project_name = simple_sanitize ( project . name )
push_to_schema_breadcrumb ( project_name , project_path ( project ) )
link_to project_path ( project ) do
icon = project_icon ( project , alt : project_name , class : 'avatar-tile' , width : 15 , height : 15 ) if project . avatar_url && ! Rails . env . test?
[ icon , content_tag ( " span " , project_name , class : " breadcrumb-item-text js-breadcrumb-item-text " ) ] . join . html_safe
end
end
def build_namespace_breadcrumb_link ( project )
if project . group
group_title ( project . group , nil , nil )
else
owner = project . namespace . owner
name = simple_sanitize ( owner . name )
url = user_path ( owner )
push_to_schema_breadcrumb ( name , url )
link_to ( name , url )
end
end
2012-09-07 16:57:13 +00:00
end
2020-04-21 15:21:10 +00:00
ProjectsHelper . prepend_if_ee ( 'EE::ProjectsHelper' )