2024-10-28 21:15:05 +01:00
< script lang = "ts" setup >
import { computed , onMounted , onUnmounted , ref , watch } from 'vue' ;
2024-07-07 17:32:30 +02:00
import { SvgIcon } from '../svg.ts' ;
import { toggleElem } from '../utils/dom.ts' ;
2023-09-02 16:59:07 +02:00
const { csrfToken , pageData } = window . config ;
2024-10-28 21:15:05 +01:00
const mergeForm = ref ( pageData . pullRequestMergeForm ) ;
const mergeTitleFieldValue = ref ( '' ) ;
const mergeMessageFieldValue = ref ( '' ) ;
const deleteBranchAfterMerge = ref ( false ) ;
const autoMergeWhenSucceed = ref ( false ) ;
const mergeStyle = ref ( '' ) ;
const mergeStyleDetail = ref ( {
hideMergeMessageTexts : false ,
textDoMerge : '' ,
mergeTitleFieldText : '' ,
mergeMessageFieldText : '' ,
hideAutoMerge : false ,
} ) ;
const mergeStyleAllowedCount = ref ( 0 ) ;
const showMergeStyleMenu = ref ( false ) ;
const showActionForm = ref ( false ) ;
const mergeButtonStyleClass = computed ( ( ) => {
if ( mergeForm . value . allOverridableChecksOk ) return 'primary' ;
return autoMergeWhenSucceed . value ? 'primary' : 'red' ;
} ) ;
const forceMerge = computed ( ( ) => {
return mergeForm . value . canMergeNow && ! mergeForm . value . allOverridableChecksOk ;
} ) ;
watch ( mergeStyle , ( val ) => {
mergeStyleDetail . value = mergeForm . value . mergeStyles . find ( ( e ) => e . name === val ) ;
for ( const elem of document . querySelectorAll ( '[data-pull-merge-style]' ) ) {
toggleElem ( elem , elem . getAttribute ( 'data-pull-merge-style' ) === val ) ;
}
} ) ;
onMounted ( ( ) => {
mergeStyleAllowedCount . value = mergeForm . value . mergeStyles . reduce ( ( v , msd ) => v + ( msd . allowed ? 1 : 0 ) , 0 ) ;
let mergeStyle = mergeForm . value . mergeStyles . find ( ( e ) => e . allowed && e . name === mergeForm . value . defaultMergeStyle ) ? . name ;
if ( ! mergeStyle ) mergeStyle = mergeForm . value . mergeStyles . find ( ( e ) => e . allowed ) ? . name ;
switchMergeStyle ( mergeStyle , ! mergeForm . value . canMergeNow ) ;
document . addEventListener ( 'mouseup' , hideMergeStyleMenu ) ;
} ) ;
onUnmounted ( ( ) => {
document . removeEventListener ( 'mouseup' , hideMergeStyleMenu ) ;
} ) ;
function hideMergeStyleMenu ( ) {
showMergeStyleMenu . value = false ;
}
function toggleActionForm ( show : boolean ) {
showActionForm . value = show ;
if ( ! show ) return ;
deleteBranchAfterMerge . value = mergeForm . value . defaultDeleteBranchAfterMerge ;
mergeTitleFieldValue . value = mergeStyleDetail . value . mergeTitleFieldText ;
mergeMessageFieldValue . value = mergeStyleDetail . value . mergeMessageFieldText ;
}
function switchMergeStyle ( name , autoMerge = false ) {
mergeStyle . value = name ;
autoMergeWhenSucceed . value = autoMerge ;
}
function clearMergeMessage ( ) {
mergeMessageFieldValue . value = mergeForm . value . defaultMergeMessage ;
}
2023-09-02 16:59:07 +02:00
< / script >
2024-10-28 21:15:05 +01:00
2022-05-12 15:39:02 +02:00
< template >
2022-06-11 16:44:20 +02:00
<!--
2022-10-09 09:17:01 +02:00
if this component is shown , either the user is an admin ( can do a merge without checks ) , or they are a writer who has the permission to do a merge
if the user is a writer and can ' t do a merge now ( canMergeNow == false ) , then only show the Auto Merge for them
2022-06-11 16:44:20 +02:00
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 15:39:02 +02:00
< div >
2023-03-14 10:51:20 +01:00
<!-- eslint - disable - next - line vue / no - v - html -- >
< div v-if = "mergeForm.hasPendingPullRequestMerge" v-html="mergeForm.hasPendingPullRequestMergeTip" class = "ui info message" / >
2022-06-11 16:44:20 +02:00
2024-03-22 12:17:30 +01:00
<!-- another similar form is in pull . tmpl ( manual merge ) -- >
2024-01-14 23:00:47 +01:00
< form class = "ui form form-fetch-action" v-if = "showActionForm" :action="mergeForm.baseLink+'/merge'" method="post" >
< input type = "hidden" name = "_csrf" :value = "csrfToken" >
< input type = "hidden" name = "head_commit_id" v-model = "mergeForm.pullHeadCommitID" >
< input type = "hidden" name = "merge_when_checks_succeed" v-model = "autoMergeWhenSucceed" >
< input type = "hidden" name = "force_merge" v-model = "forceMerge" >
2022-05-12 15:39:02 +02:00
2024-01-14 23:00:47 +01:00
< template v-if = "!mergeStyleDetail.hideMergeMessageTexts" >
< div class = "field" >
< input type = "text" name = "merge_title_field" v-model = "mergeTitleFieldValue" >
2023-02-21 11:03:41 +01:00
< / div >
2024-01-14 23:00:47 +01:00
< div class = "field" >
< textarea name = "merge_message_field" rows = "5" :placeholder = "mergeForm.mergeMessageFieldPlaceHolder" v -model = " mergeMessageFieldValue " / >
< template v-if = "mergeMessageFieldValue !== mergeForm.defaultMergeMessage" >
Migrate margin and padding helpers to tailwind (#30043)
This will conclude the refactor of 1:1 class replacements to tailwind,
except `gt-hidden`. Commands ran:
```bash
perl -p -i -e 's#gt-(p|m)([lrtbxy])?-0#tw-$1$2-0#g' {web_src/js,templates,routers,services}/**/*
perl -p -i -e 's#gt-(p|m)([lrtbxy])?-1#tw-$1$2-0.5#g' {web_src/js,templates,routers,services}/**/*
perl -p -i -e 's#gt-(p|m)([lrtbxy])?-2#tw-$1$2-1#g' {web_src/js,templates,routers,services}/**/*
perl -p -i -e 's#gt-(p|m)([lrtbxy])?-3#tw-$1$2-2#g' {web_src/js,templates,routers,services}/**/*
perl -p -i -e 's#gt-(p|m)([lrtbxy])?-4#tw-$1$2-4#g' {web_src/js,templates,routers,services}/**/*
perl -p -i -e 's#gt-(p|m)([lrtbxy])?-5#tw-$1$2-8#g' {web_src/js,templates,routers,services}/**/*
```
2024-03-24 17:42:49 +01:00
< button @click.prevent ="clearMergeMessage" class = "btn tw-mt-1 tw-p-1 interact-fg" :data-tooltip-content = "mergeForm.textClearMergeMessageHint" >
2024-01-14 23:00:47 +01:00
{ { mergeForm . textClearMergeMessage } }
< / button >
2022-06-11 16:44:20 +02:00
< / template >
2024-01-14 23:00:47 +01:00
< / div >
< / template >
2022-05-12 15:39:02 +02:00
2024-01-14 23:00:47 +01:00
< div class = "field" v-if = "mergeStyle === 'manually-merged'" >
< input type = "text" name = "merge_commit_id" :placeholder = "mergeForm.textMergeCommitId" >
< / div >
2022-05-12 15:39:02 +02:00
2024-01-14 23:00:47 +01:00
< button class = "ui button" :class = "mergeButtonStyleClass" type = "submit" name = "do" :value = "mergeStyle" >
{ { mergeStyleDetail . textDoMerge } }
< template v-if = "autoMergeWhenSucceed" >
{ { mergeForm . textAutoMergeButtonWhenSucceed } }
< / template >
< / button >
< button class = "ui button merge-cancel" @click ="toggleActionForm(false)" >
{ { mergeForm . textCancel } }
< / button >
Migrate margin and padding helpers to tailwind (#30043)
This will conclude the refactor of 1:1 class replacements to tailwind,
except `gt-hidden`. Commands ran:
```bash
perl -p -i -e 's#gt-(p|m)([lrtbxy])?-0#tw-$1$2-0#g' {web_src/js,templates,routers,services}/**/*
perl -p -i -e 's#gt-(p|m)([lrtbxy])?-1#tw-$1$2-0.5#g' {web_src/js,templates,routers,services}/**/*
perl -p -i -e 's#gt-(p|m)([lrtbxy])?-2#tw-$1$2-1#g' {web_src/js,templates,routers,services}/**/*
perl -p -i -e 's#gt-(p|m)([lrtbxy])?-3#tw-$1$2-2#g' {web_src/js,templates,routers,services}/**/*
perl -p -i -e 's#gt-(p|m)([lrtbxy])?-4#tw-$1$2-4#g' {web_src/js,templates,routers,services}/**/*
perl -p -i -e 's#gt-(p|m)([lrtbxy])?-5#tw-$1$2-8#g' {web_src/js,templates,routers,services}/**/*
```
2024-03-24 17:42:49 +01:00
< div class = "ui checkbox tw-ml-1" v-if = "mergeForm.isPullBranchDeletable && !autoMergeWhenSucceed" >
2024-01-14 23:00:47 +01: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 >
2022-05-12 15:39:02 +02:00
2024-03-22 14:45:10 +01:00
< div v-if = "!showActionForm" class="tw-flex" >
2022-06-11 16:44:20 +02:00
<!-- the merge button -- >
2024-04-14 19:53:52 +02:00
< div class = "ui buttons merge-button" : class = "[mergeForm.emptyCommit ? '' : mergeForm.allOverridableChecksOk ? 'primary' : 'red']" @click ="toggleActionForm(true)" >
2022-05-12 15:39:02 +02: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 15:39:02 +02:00
< / button >
2023-06-14 18:40:15 +02:00
< div class = "ui dropdown icon button" @ click.stop = " showMergeStyleMenu = ! showMergeStyleMenu " v-if = "mergeStyleAllowedCount>1" >
2022-05-12 15:39:02 +02:00
< 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 15:39:02 +02:00
< / div >
< / template >
< / div >
< / div >
< / div >
2022-06-11 16:44:20 +02:00
<!-- the cancel auto merge button -- >
Migrate margin and padding helpers to tailwind (#30043)
This will conclude the refactor of 1:1 class replacements to tailwind,
except `gt-hidden`. Commands ran:
```bash
perl -p -i -e 's#gt-(p|m)([lrtbxy])?-0#tw-$1$2-0#g' {web_src/js,templates,routers,services}/**/*
perl -p -i -e 's#gt-(p|m)([lrtbxy])?-1#tw-$1$2-0.5#g' {web_src/js,templates,routers,services}/**/*
perl -p -i -e 's#gt-(p|m)([lrtbxy])?-2#tw-$1$2-1#g' {web_src/js,templates,routers,services}/**/*
perl -p -i -e 's#gt-(p|m)([lrtbxy])?-3#tw-$1$2-2#g' {web_src/js,templates,routers,services}/**/*
perl -p -i -e 's#gt-(p|m)([lrtbxy])?-4#tw-$1$2-4#g' {web_src/js,templates,routers,services}/**/*
perl -p -i -e 's#gt-(p|m)([lrtbxy])?-5#tw-$1$2-8#g' {web_src/js,templates,routers,services}/**/*
```
2024-03-24 17:42:49 +01:00
< form v-if = "mergeForm.hasPendingPullRequestMerge" :action="mergeForm.baseLink+'/cancel_auto_merge'" method="post" class="tw-ml-4" >
2022-06-11 16:44:20 +02:00
< input type = "hidden" name = "_csrf" :value = "csrfToken" >
< button class = "ui button" >
{ { mergeForm . textAutoMergeCancelSchedule } }
< / button >
< / form >
< / div >
2022-05-12 15:39:02 +02:00
< / div >
< / template >
2024-10-28 21:15:05 +01:00
2022-05-12 15:39:02 +02:00
< 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 15:39:02 +02:00
< / style >