2022-05-12 21:39:02 +08:00
< template >
2022-06-11 16:44:20 +02:00
<!--
if this component is shown , either the user is admin ( can do merge without checks ) , or they is a writer who has the permission to do merge
if the user is a writer and can 't do merge now (canMergeNow==false), then only show the Auto Merge for them
How to test the UI manually:
* Method 1: manually set some variables in pull.tmpl, eg: {{$notAllOverridableChecksOk = true}} {{$canMergeNow = false}}
* Method 2: make a protected branch, then set state=pending/success :
curl -X POST ${root_url}/api/v1/repos/${owner}/${repo}/statuses/${sha} \
-H "accept: application/json" -H "authorization: Basic $base64_auth" -H "Content-Type: application/json" \
-d ' { "context" : "test/context" , "description" : "description" , "state" : "${state}" , "target_url" : "http://localhost" } '
-->
2022-05-12 21:39:02 +08:00
<div>
2022-06-11 16:44:20 +02:00
<!-- eslint-disable -->
<div v-if="mergeForm.hasPendingPullRequestMerge" v-html="mergeForm.hasPendingPullRequestMergeTip" class="ui info message"></div>
2022-05-12 21:39:02 +08:00
<div class="ui form" v-if="showActionForm">
<form :action="mergeForm.baseLink+' / merge ' " method=" post ">
<input type=" hidden " name=" _csrf " :value=" csrfToken ">
<input type=" hidden " name=" head _commit _id " v-model=" mergeForm . pullHeadCommitID ">
2022-06-11 16:44:20 +02:00
<input type=" hidden " name=" merge _when _checks _succeed " v-model=" autoMergeWhenSucceed ">
2022-05-12 21:39:02 +08:00
<template v-if=" ! mergeStyleDetail . hideMergeMessageTexts ">
<div class=" field ">
<input type=" text " name=" merge _title _field " v-model=" mergeTitleFieldValue ">
</div>
<div class=" field ">
<textarea name=" merge _message _field " rows=" 5 " :placeholder=" mergeForm . mergeMessageFieldPlaceHolder " v-model=" mergeMessageFieldValue "/>
</div>
</template>
2022-06-11 16:44:20 +02:00
<button class=" ui button " :class=" mergeButtonStyleClass " type=" submit " name=" do " :value=" mergeStyle ">
2022-05-12 21:39:02 +08:00
{{ mergeStyleDetail.textDoMerge }}
2022-06-11 16:44:20 +02:00
<template v-if=" autoMergeWhenSucceed ">
{{ mergeForm.textAutoMergeButtonWhenSucceed }}
</template>
2022-05-12 21:39:02 +08:00
</button>
<button class=" ui button merge - cancel " @click=" toggleActionForm ( false ) ">
{{ mergeForm.textCancel }}
</button>
2022-06-11 16:44:20 +02:00
<div class=" ui checkbox ml - 2 " v-if=" mergeForm . isPullBranchDeletable && ! autoMergeWhenSucceed ">
2022-05-12 21:39:02 +08:00
<input name=" delete _branch _after _merge " type=" checkbox " v-model=" deleteBranchAfterMerge " id=" delete - branch - after - merge ">
<label for=" delete - branch - after - merge ">{{ mergeForm.textDeleteBranch }}</label>
</div>
</form>
</div>
2022-06-11 16:44:20 +02:00
<div v-if=" ! showActionForm " class=" df ">
<!-- the merge button -->
<div class=" ui buttons merge - button " :class=" mergeButtonStyleClass " @click=" toggleActionForm ( true ) " >
2022-05-12 21:39:02 +08:00
<button class=" ui button ">
<svg-icon name=" octicon - git - merge "/>
2022-06-11 16:44:20 +02:00
<span class=" button - text ">
{{ mergeStyleDetail.textDoMerge }}
<template v-if=" autoMergeWhenSucceed ">
{{ mergeForm.textAutoMergeButtonWhenSucceed }}
</template>
</span>
2022-05-12 21:39:02 +08:00
</button>
<div class=" ui dropdown icon button no - text " @click.stop=" showMergeStyleMenu = ! showMergeStyleMenu " v-if=" mergeStyleAllowedCount > 1 ">
<svg-icon name=" octicon - triangle - down " :size=" 14 "/>
<div class=" menu " :class=" { 'show' : showMergeStyleMenu } ">
<template v-for=" msd in mergeForm . mergeStyles ">
2022-06-11 16:44:20 +02:00
<!-- if can merge now, show one action " merge now ", and an action " auto merge when succeed " -->
<div class=" item " v-if=" msd . allowed && mergeForm . canMergeNow " :key=" msd . name " @click.stop=" switchMergeStyle ( msd . name ) ">
<div class=" action - text ">
{{ msd.textDoMerge }}
</div>
<div v-if=" ! msd . hideAutoMerge " class=" auto - merge - small " @click.stop=" switchMergeStyle ( msd . name , true ) ">
<svg-icon name=" octicon - clock " :size=" 14 "/>
<div class=" auto - merge - tip ">
{{ mergeForm.textAutoMergeWhenSucceed }}
</div>
</div>
</div>
<!-- if can NOT merge now, only show one action " auto merge when succeed " -->
<div class=" item " v-if=" msd . allowed && ! mergeForm . canMergeNow && ! msd . hideAutoMerge " :key=" msd . name " @click.stop=" switchMergeStyle ( msd . name , true ) ">
<div class=" action - text ">
{{ msd.textDoMerge }} {{ mergeForm.textAutoMergeButtonWhenSucceed }}
</div>
2022-05-12 21:39:02 +08:00
</div>
</template>
</div>
</div>
</div>
2022-06-11 16:44:20 +02:00
<!-- the cancel auto merge button -->
<form v-if=" mergeForm . hasPendingPullRequestMerge " :action=" mergeForm . baseLink + '/cancel_auto_merge' " method=" post " class=" ml - 4 ">
<input type=" hidden " name=" _csrf " :value=" csrfToken ">
<button class=" ui button " >
{ { mergeForm . textAutoMergeCancelSchedule } }
< / button >
< / form >
< / div >
2022-05-12 21:39:02 +08:00
< / div >
< / template >
< script >
import { SvgIcon } from '../svg.js' ;
const { csrfToken , pageData } = window . config ;
export default {
name : 'PullRequestMergeForm' ,
components : {
SvgIcon ,
} ,
data : ( ) => ( {
csrfToken ,
mergeForm : pageData . pullRequestMergeForm ,
mergeTitleFieldValue : '' ,
mergeMessageFieldValue : '' ,
deleteBranchAfterMerge : false ,
2022-06-11 16:44:20 +02:00
autoMergeWhenSucceed : false ,
2022-05-12 21:39:02 +08:00
mergeStyle : '' ,
mergeStyleDetail : { // dummy only, these values will come from one of the mergeForm.mergeStyles
hideMergeMessageTexts : false ,
textDoMerge : '' ,
mergeTitleFieldText : '' ,
mergeMessageFieldText : '' ,
} ,
mergeStyleAllowedCount : 0 ,
showMergeStyleMenu : false ,
showActionForm : false ,
} ) ,
2022-06-11 16:44:20 +02:00
computed : {
mergeButtonStyleClass ( ) {
if ( this . mergeForm . allOverridableChecksOk ) return 'green' ;
return this . autoMergeWhenSucceed ? 'blue' : 'red' ;
}
} ,
2022-05-12 21:39:02 +08:00
watch : {
mergeStyle ( val ) {
this . mergeStyleDetail = this . mergeForm . mergeStyles . find ( ( e ) => e . name === val ) ;
}
} ,
created ( ) {
this . mergeStyleAllowedCount = this . mergeForm . mergeStyles . reduce ( ( v , msd ) => v + ( msd . allowed ? 1 : 0 ) , 0 ) ;
2022-06-11 16:44:20 +02:00
this . switchMergeStyle ( this . mergeForm . mergeStyles . find ( ( e ) => e . allowed ) ? . name , ! this . mergeForm . canMergeNow ) ;
2022-05-12 21:39:02 +08:00
} ,
mounted ( ) {
document . addEventListener ( 'mouseup' , this . hideMergeStyleMenu ) ;
} ,
unmounted ( ) {
document . removeEventListener ( 'mouseup' , this . hideMergeStyleMenu ) ;
} ,
methods : {
hideMergeStyleMenu ( ) {
this . showMergeStyleMenu = false ;
} ,
toggleActionForm ( show ) {
this . showActionForm = show ;
if ( ! show ) return ;
this . deleteBranchAfterMerge = this . mergeForm . defaultDeleteBranchAfterMerge ;
this . mergeTitleFieldValue = this . mergeStyleDetail . mergeTitleFieldText ;
this . mergeMessageFieldValue = this . mergeStyleDetail . mergeMessageFieldText ;
2022-06-11 16:44:20 +02:00
} ,
switchMergeStyle ( name , autoMerge = false ) {
this . mergeStyle = name ;
this . autoMergeWhenSucceed = autoMerge ;
} ,
2022-05-12 21:39:02 +08:00
} ,
} ;
< / script >
< style scoped >
/* to keep UI the same, at the moment we are still using some Fomantic UI styles, but we do not use their scripts, so we need to fine tune some styles */
. ui . dropdown . menu . show {
display : block ;
}
. ui . checkbox label {
cursor : pointer ;
}
2022-06-11 16:44:20 +02:00
/* make the dropdown list left-aligned */
. ui . merge - button {
position : relative ;
}
. ui . merge - button . ui . dropdown {
position : static ;
}
. ui . merge - button > . ui . dropdown : last - child > . menu : not ( . left ) {
left : 0 ;
right : auto ;
}
. ui . merge - button . ui . dropdown . menu > . item {
display : flex ;
align - items : stretch ;
padding : 0 ! important ; /* polluted by semantic.css: .ui.dropdown .menu > .item { !important } */
}
/* merge style list item */
. action - text {
padding : 0.8 rem ;
flex : 1
}
. auto - merge - small {
width : 40 px ;
display : flex ;
align - items : center ;
justify - content : center ;
position : relative ;
}
. auto - merge - small . auto - merge - tip {
display : none ;
left : 38 px ;
top : - 1 px ;
bottom : - 1 px ;
position : absolute ;
align - items : center ;
color : var ( -- color - info - text ) ;
background - color : var ( -- color - info - bg ) ;
border : 1 px solid var ( -- color - info - border ) ;
border - left : none ;
padding - right : 1 rem ;
}
. auto - merge - small : hover {
color : var ( -- color - info - text ) ;
background - color : var ( -- color - info - bg ) ;
border : 1 px solid var ( -- color - info - border ) ;
}
. auto - merge - small : hover . auto - merge - tip {
display : flex ;
}
2022-05-12 21:39:02 +08:00
< / style >