2018-08-18 07:19:57 -04:00
# frozen_string_literal: true
2011-11-28 02:39:43 -05:00
module MergeRequestsHelper
2019-12-02 22:06:35 -05:00
include Gitlab :: Utils :: StrongMemoize
2022-07-25 17:08:32 -04:00
def create_mr_button_from_event? ( event )
create_mr_button? ( from : event . branch_name , source_project : event . project )
2015-11-17 12:53:56 -05:00
end
2022-07-25 17:08:32 -04:00
def create_mr_path_from_push_event ( event )
create_mr_path ( from : event . branch_name , source_project : event . project )
2015-11-17 12:53:56 -05:00
end
2014-09-25 18:07:40 -04:00
def mr_css_classes ( mr )
2018-08-18 07:19:57 -04:00
classes = [ " merge-request " ]
classes << " closed " if mr . closed?
classes << " merged " if mr . merged?
classes . join ( ' ' )
2012-06-21 01:29:53 -04:00
end
2012-11-20 12:34:05 -05:00
2022-07-28 14:09:03 -04:00
def merge_path_description ( merge_request , with_arrow : false )
2013-07-17 10:35:11 -04:00
if merge_request . for_fork?
2022-07-28 14:09:03 -04:00
msg = if with_arrow
_ ( " Project:Branches: %{source_project_path}:%{source_branch} → %{target_project_path}:%{target_branch} " )
else
_ ( " Project:Branches: %{source_project_path}:%{source_branch} to %{target_project_path}:%{target_branch} " )
end
msg % {
source_project_path : merge_request . source_project_path ,
source_branch : merge_request . source_branch ,
target_project_path : merge_request . target_project . full_path ,
target_branch : merge_request . target_branch
}
2013-07-17 10:35:11 -04:00
else
2022-07-28 14:09:03 -04:00
msg = if with_arrow
_ ( " Branches: %{source_branch} → %{target_branch} " )
else
_ ( " Branches: %{source_branch} to %{target_branch} " )
end
msg % {
source_branch : merge_request . source_branch ,
target_branch : merge_request . target_branch
}
2013-07-17 10:35:11 -04:00
end
end
2014-06-13 08:38:10 -04:00
2015-05-06 08:13:11 -04:00
def mr_change_branches_path ( merge_request )
2017-06-29 13:06:35 -04:00
project_new_merge_request_path (
@project ,
2015-05-06 08:13:11 -04:00
merge_request : {
2017-02-14 08:43:12 -05:00
source_project_id : merge_request . source_project_id ,
target_project_id : merge_request . target_project_id ,
2018-11-07 08:32:20 -05:00
source_branch : merge_request . source_branch ,
2017-05-03 07:22:03 -04:00
target_branch : merge_request . target_branch
2015-12-02 08:22:33 -05:00
} ,
change_branches : true
2015-05-06 08:13:11 -04:00
)
end
2015-08-07 10:04:17 -04:00
2015-09-30 23:50:53 -04:00
def format_mr_branch_names ( merge_request )
source_path = merge_request . source_project_path
target_path = merge_request . target_project_path
source_branch = merge_request . source_branch
target_branch = merge_request . target_branch
if source_path == target_path
[ source_branch , target_branch ]
else
[ " #{ source_path } : #{ source_branch } " , " #{ target_path } : #{ target_branch } " ]
end
end
2016-07-11 03:51:18 -04:00
2017-04-26 18:04:07 -04:00
def target_projects ( project )
2017-09-20 11:41:11 -04:00
MergeRequestTargetProjectFinder . new ( current_user : current_user , source_project : project )
2019-12-17 04:07:48 -05:00
. execute ( include_routes : true )
2017-04-26 18:04:07 -04:00
end
2016-07-11 03:51:18 -04:00
def merge_request_button_visibility ( merge_request , closed )
2018-09-20 10:41:15 -04:00
return 'hidden' if merge_request_button_hidden? ( merge_request , closed )
end
def merge_request_button_hidden? ( merge_request , closed )
2020-12-08 10:09:45 -05:00
merge_request . closed? == closed || ( merge_request . merged? == closed && ! merge_request . closed? ) || merge_request . closed_or_merged_without_fork?
2016-07-11 03:51:18 -04:00
end
2016-08-31 09:30:54 -04:00
2016-09-06 11:35:27 -04:00
def merge_request_version_path ( project , merge_request , merge_request_diff , start_sha = nil )
2017-06-29 13:06:35 -04:00
diffs_project_merge_request_path ( project , merge_request , diff_id : merge_request_diff . id , start_sha : start_sha )
2016-08-31 09:30:54 -04:00
end
2016-09-06 13:08:06 -04:00
2017-02-01 09:28:04 -05:00
def merge_params ( merge_request )
{
2019-05-22 07:45:27 -04:00
auto_merge_strategy : AutoMergeService :: STRATEGY_MERGE_WHEN_PIPELINE_SUCCEEDS ,
2017-02-01 09:28:04 -05:00
should_remove_source_branch : true ,
2018-05-29 05:51:43 -04:00
sha : merge_request . diff_head_sha ,
2020-06-30 14:09:13 -04:00
squash : merge_request . squash_on_merge?
2018-05-29 05:51:43 -04:00
}
2017-02-01 09:28:04 -05:00
end
2017-12-01 14:08:30 -05:00
def tab_link_for ( merge_request , tab , options = { } , & block )
2017-11-08 15:39:29 -05:00
data_attrs = {
action : tab . to_s ,
2017-12-01 14:08:30 -05:00
target : " # #{ tab } " ,
2018-06-30 09:17:46 -04:00
toggle : options . fetch ( :force_link , false ) ? '' : 'tabvue'
2017-11-08 15:39:29 -05:00
}
url = case tab
2017-12-01 14:08:30 -05:00
when :show
data_attrs [ :target ] = '#notes'
method ( :project_merge_request_path )
when :commits
method ( :commits_project_merge_request_path )
when :pipelines
method ( :pipelines_project_merge_request_path )
when :diffs
method ( :diffs_project_merge_request_path )
else
raise " Cannot create tab #{ tab } . "
end
link_to ( url [ merge_request . project , merge_request ] , data : data_attrs , & block )
2017-11-08 15:39:29 -05:00
end
2018-05-22 21:54:57 -04:00
def allow_collaboration_unavailable_reason ( merge_request )
return if merge_request . can_allow_collaboration? ( current_user )
2018-02-23 12:30:37 -05:00
minimum_visibility = [ merge_request . target_project . visibility_level ,
merge_request . source_project . visibility_level ] . min
if minimum_visibility < Gitlab :: VisibilityLevel :: INTERNAL
_ ( 'Not available for private projects' )
elsif ProtectedBranch . protected? ( merge_request . source_project , merge_request . source_branch )
_ ( 'Not available for protected branches' )
end
end
2018-04-06 10:04:48 -04:00
def merge_request_source_project_for_project ( project = @project )
unless can? ( current_user , :create_merge_request_in , project )
2019-02-08 07:19:53 -05:00
return
2018-04-06 10:04:48 -04:00
end
if can? ( current_user , :create_merge_request_from , project )
project
else
current_user . fork_of ( project )
end
end
2020-12-03 13:10:10 -05:00
def toggle_draft_merge_request_path ( issuable )
2022-06-08 20:08:57 -04:00
wip_event = issuable . draft? ? 'ready' : 'draft'
2020-12-03 13:10:10 -05:00
issuable_path ( issuable , { merge_request : { wip_event : wip_event } } )
end
2021-01-04 19:10:20 -05:00
def user_merge_requests_counts
@user_merge_requests_counts || = begin
assigned_count = assigned_issuables_count ( :merge_requests )
review_requested_count = review_requested_merge_requests_count
total_count = assigned_count + review_requested_count
2022-08-17 05:11:44 -04:00
{
2021-01-04 19:10:20 -05:00
assigned : assigned_count ,
review_requested : review_requested_count ,
total : total_count
}
end
end
2021-03-02 01:10:53 -05:00
def reviewers_label ( merge_request , include_value : true )
reviewers = merge_request . reviewers
if include_value
sanitized_list = sanitize_name ( reviewers . map ( & :name ) . to_sentence )
2021-03-19 02:09:30 -04:00
ns_ ( 'NotificationEmail|Reviewer: %{users}' , 'NotificationEmail|Reviewers: %{users}' , reviewers . count ) % { users : sanitized_list }
2021-03-02 01:10:53 -05:00
else
2021-03-19 02:09:30 -04:00
ns_ ( 'NotificationEmail|Reviewer' , 'NotificationEmail|Reviewers' , reviewers . count )
2021-03-02 01:10:53 -05:00
end
end
2021-04-02 20:09:02 -04:00
def diffs_tab_pane_data ( project , merge_request , params )
{
" is-locked " : merge_request . discussion_locked? ,
endpoint : diffs_project_merge_request_path ( project , merge_request , 'json' , params ) ,
endpoint_metadata : @endpoint_metadata_url ,
endpoint_batch : diffs_batch_project_json_merge_request_path ( project , merge_request , 'json' , params ) ,
endpoint_coverage : @coverage_path ,
2022-04-13 14:08:33 -04:00
help_page_path : help_page_path ( 'user/project/merge_requests/reviews/suggestions.md' ) ,
2021-04-02 20:09:02 -04:00
current_user_data : @current_user_data ,
update_current_user_path : @update_current_user_path ,
project_path : project_path ( merge_request . project ) ,
changes_empty_state_illustration : image_path ( 'illustrations/merge_request_changes_empty.svg' ) ,
is_fluid_layout : fluid_layout . to_s ,
2021-12-10 13:14:42 -05:00
dismiss_endpoint : callouts_path ,
2021-04-02 20:09:02 -04:00
show_suggest_popover : show_suggest_popover? . to_s ,
show_whitespace_default : @show_whitespace_default . to_s ,
file_by_file_default : @file_by_file_default . to_s ,
2021-08-10 08:11:00 -04:00
default_suggestion_commit_message : default_suggestion_commit_message ,
source_project_default_url : @merge_request . source_project && default_url_to_repo ( @merge_request . source_project ) ,
source_project_full_path : @merge_request . source_project & . full_path ,
is_forked : @project . forked? . to_s
2021-04-02 20:09:02 -04:00
}
end
2021-04-08 11:09:06 -04:00
def award_emoji_merge_request_api_path ( merge_request )
2022-03-23 11:08:38 -04:00
api_v4_projects_merge_requests_award_emoji_path ( id : merge_request . project . id , merge_request_iid : merge_request . iid )
2021-04-08 11:09:06 -04:00
end
2022-04-28 11:10:08 -04:00
def how_merge_modal_data ( merge_request )
{
2022-05-03 08:07:28 -04:00
is_fork : merge_request . for_fork? . to_s ,
can_merge : merge_request . can_be_merged_by? ( current_user ) . to_s ,
2022-04-28 11:10:08 -04:00
source_branch : merge_request . source_branch ,
2022-05-06 11:09:03 -04:00
source_project_path : merge_request . source_project & . path ,
2022-04-28 11:10:08 -04:00
source_project_full_path : merge_request . source_project & . full_path ,
2022-05-03 08:07:28 -04:00
source_project_default_url : merge_request . source_project && default_url_to_repo ( merge_request . source_project ) ,
2022-04-28 11:10:08 -04:00
target_branch : merge_request . target_branch ,
reviewing_docs_path : help_page_path ( 'user/project/merge_requests/reviews/index.md' , anchor : " checkout-merge-requests-locally-through-the-head-ref " )
}
end
2021-01-04 19:10:20 -05:00
private
def review_requested_merge_requests_count
current_user . review_requested_open_merge_requests_count
end
2021-01-19 07:10:46 -05:00
def default_suggestion_commit_message
@project . suggestion_commit_message . presence || Gitlab :: Suggestions :: CommitMessage :: DEFAULT_SUGGESTION_COMMIT_MESSAGE
end
2022-05-09 17:07:53 -04:00
def merge_request_source_branch ( merge_request )
branch = if merge_request . for_fork?
" #{ merge_request . source_project_path } : #{ merge_request . source_branch } "
else
merge_request . source_branch
end
branch_path = if merge_request . source_project
project_tree_path ( merge_request . source_project , merge_request . source_branch )
else
''
end
2022-05-24 17:09:08 -04:00
link_to branch , branch_path , title : branch , class : 'gl-text-blue-500! gl-font-monospace gl-bg-blue-50 gl-rounded-base gl-font-sm gl-px-2 gl-display-inline-block gl-text-truncate gl-max-w-26 gl-mb-n2'
2022-05-09 17:07:53 -04:00
end
def merge_request_header ( project , merge_request )
link_to_author = link_to_member ( project , merge_request . author , size : 24 , extra_class : 'gl-font-weight-bold' , avatar : false )
copy_button = clipboard_button ( text : merge_request . source_branch , title : _ ( 'Copy branch name' ) , class : 'btn btn-default btn-sm gl-button btn-default-tertiary btn-icon gl-display-none! gl-md-display-inline-block! js-source-branch-copy' )
2022-05-24 17:09:08 -04:00
target_branch = link_to merge_request . target_branch , project_tree_path ( merge_request . target_project , merge_request . target_branch ) , title : merge_request . target_branch , class : 'gl-text-blue-500! gl-font-monospace gl-bg-blue-50 gl-rounded-base gl-font-sm gl-px-2 gl-display-inline-block gl-text-truncate gl-max-w-26 gl-mb-n2'
2022-05-09 17:07:53 -04:00
2022-05-11 14:07:55 -04:00
_ ( '%{author} requested to merge %{source_branch} %{copy_button} into %{target_branch} %{created_at}' ) . html_safe % { author : link_to_author . html_safe , source_branch : merge_request_source_branch ( merge_request ) . html_safe , copy_button : copy_button . html_safe , target_branch : target_branch . html_safe , created_at : time_ago_with_tooltip ( merge_request . created_at , html_class : 'gl-display-inline-block' ) . html_safe }
2022-05-09 17:07:53 -04:00
end
2022-05-16 17:09:09 -04:00
def moved_mr_sidebar_enabled?
Feature . enabled? ( :moved_mr_sidebar , @project ) && defined? ( @merge_request )
end
2022-08-26 08:11:48 -04:00
def sticky_header_data
data = {
iid : @merge_request . iid ,
projectPath : @project . full_path ,
title : markdown_field ( @merge_request , :title ) ,
2022-09-12 02:13:23 -04:00
isFluidLayout : fluid_layout . to_s ,
2022-08-26 08:11:48 -04:00
tabs : [
[ 'show' , _ ( 'Overview' ) , project_merge_request_path ( @project , @merge_request ) , @merge_request . related_notes . user . count ] ,
[ 'commits' , _ ( 'Commits' ) , commits_project_merge_request_path ( @project , @merge_request ) , @commits_count ] ,
[ 'diffs' , _ ( 'Changes' ) , diffs_project_merge_request_path ( @project , @merge_request ) , @diffs_count ]
]
}
if @project . builds_enabled?
data [ :tabs ] . insert ( 2 , [ 'pipelines' , _ ( 'Pipelines' ) , pipelines_project_merge_request_path ( @project , @merge_request ) , @number_of_pipelines ] )
end
data
end
2011-11-28 02:39:43 -05:00
end
2019-09-13 09:26:31 -04:00
2021-05-11 17:10:21 -04:00
MergeRequestsHelper . prepend_mod_with ( 'MergeRequestsHelper' )