Refactor pull request view (4) (#37451)
Use JSON attribute instead of inline script --------- Co-authored-by: Nicolas <bircni@icloud.com>
This commit is contained in:
@@ -18,7 +18,6 @@ import (
|
|||||||
"code.gitea.io/gitea/models/organization"
|
"code.gitea.io/gitea/models/organization"
|
||||||
access_model "code.gitea.io/gitea/models/perm/access"
|
access_model "code.gitea.io/gitea/models/perm/access"
|
||||||
project_model "code.gitea.io/gitea/models/project"
|
project_model "code.gitea.io/gitea/models/project"
|
||||||
pull_model "code.gitea.io/gitea/models/pull"
|
|
||||||
"code.gitea.io/gitea/models/renderhelper"
|
"code.gitea.io/gitea/models/renderhelper"
|
||||||
repo_model "code.gitea.io/gitea/models/repo"
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
"code.gitea.io/gitea/models/unit"
|
"code.gitea.io/gitea/models/unit"
|
||||||
@@ -826,6 +825,7 @@ func (prInfo *pullRequestViewInfo) prepareMergeBox(ctx *context.Context, issue *
|
|||||||
panic("impossible, issue must be the same")
|
panic("impossible, issue must be the same")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pull := issue.PullRequest
|
||||||
data := &pullMergeBoxData{}
|
data := &pullMergeBoxData{}
|
||||||
prInfo.MergeBoxData = data
|
prInfo.MergeBoxData = data
|
||||||
|
|
||||||
@@ -834,14 +834,12 @@ func (prInfo *pullRequestViewInfo) prepareMergeBox(ctx *context.Context, issue *
|
|||||||
statusCheckData = &pullCommitStatusCheckData{} // make the following logic easier, no need to keep checking "nil"
|
statusCheckData = &pullCommitStatusCheckData{} // make the following logic easier, no need to keep checking "nil"
|
||||||
}
|
}
|
||||||
|
|
||||||
pull := issue.PullRequest
|
|
||||||
canDelete := false
|
canDelete := false
|
||||||
allowMerge := false
|
allowMerge := false
|
||||||
canWriteToHeadRepo := false
|
canWriteToHeadRepo := false
|
||||||
|
|
||||||
pull_service.StartPullRequestCheckOnView(ctx, pull)
|
pull_service.StartPullRequestCheckOnView(ctx, pull)
|
||||||
|
|
||||||
ctx.Data["GetCommitMessages"] = ""
|
|
||||||
if !prInfo.IsPullRequestBroken {
|
if !prInfo.IsPullRequestBroken {
|
||||||
var err error
|
var err error
|
||||||
ctx.Data["UpdateAllowed"], ctx.Data["UpdateByRebaseAllowed"], err = pull_service.IsUserAllowedToUpdate(ctx, pull, ctx.Doer)
|
ctx.Data["UpdateAllowed"], ctx.Data["UpdateByRebaseAllowed"], err = pull_service.IsUserAllowedToUpdate(ctx, pull, ctx.Doer)
|
||||||
@@ -849,7 +847,6 @@ func (prInfo *pullRequestViewInfo) prepareMergeBox(ctx *context.Context, issue *
|
|||||||
ctx.ServerError("IsUserAllowedToUpdate", err)
|
ctx.ServerError("IsUserAllowedToUpdate", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx.Data["GetCommitMessages"] = pull_service.GetSquashMergeCommitMessages(ctx, pull)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if pull.IsFilesConflicted() {
|
if pull.IsFilesConflicted() {
|
||||||
@@ -903,59 +900,11 @@ func (prInfo *pullRequestViewInfo) prepareMergeBox(ctx *context.Context, issue *
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data.ReloadingInterval = util.Iif(pull != nil && pull.IsChecking(), 2000, 0)
|
data.ReloadingInterval = util.Iif(pull.IsChecking(), 2000, 0)
|
||||||
ctx.Data["CanWriteToHeadRepo"] = canWriteToHeadRepo
|
data.ShowMergeInstructions = canWriteToHeadRepo
|
||||||
ctx.Data["ShowMergeInstructions"] = canWriteToHeadRepo
|
data.ShowPullCommands = pull.HeadRepo != nil && !pull.HasMerged && !issue.IsClosed
|
||||||
ctx.Data["AllowMerge"] = allowMerge
|
ctx.Data["AllowMerge"] = allowMerge
|
||||||
|
|
||||||
prUnit, err := issue.Repo.GetUnit(ctx, unit.TypePullRequests)
|
|
||||||
if err != nil {
|
|
||||||
ctx.ServerError("GetUnit", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
prConfig := prUnit.PullRequestsConfig()
|
|
||||||
|
|
||||||
ctx.Data["AutodetectManualMerge"] = prConfig.AutodetectManualMerge
|
|
||||||
|
|
||||||
var mergeStyle repo_model.MergeStyle
|
|
||||||
// Check correct values and select default
|
|
||||||
if ms, ok := ctx.Data["MergeStyle"].(repo_model.MergeStyle); !ok ||
|
|
||||||
!prConfig.IsMergeStyleAllowed(ms) {
|
|
||||||
if prConfig.IsMergeStyleAllowed(prConfig.DefaultMergeStyle) && !ok {
|
|
||||||
mergeStyle = prConfig.DefaultMergeStyle
|
|
||||||
} else if prConfig.AllowMerge {
|
|
||||||
mergeStyle = repo_model.MergeStyleMerge
|
|
||||||
} else if prConfig.AllowRebase {
|
|
||||||
mergeStyle = repo_model.MergeStyleRebase
|
|
||||||
} else if prConfig.AllowRebaseMerge {
|
|
||||||
mergeStyle = repo_model.MergeStyleRebaseMerge
|
|
||||||
} else if prConfig.AllowSquash {
|
|
||||||
mergeStyle = repo_model.MergeStyleSquash
|
|
||||||
} else if prConfig.AllowFastForwardOnly {
|
|
||||||
mergeStyle = repo_model.MergeStyleFastForwardOnly
|
|
||||||
} else if prConfig.AllowManualMerge {
|
|
||||||
mergeStyle = repo_model.MergeStyleManuallyMerged
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.Data["MergeStyle"] = mergeStyle
|
|
||||||
|
|
||||||
defaultMergeMessage, defaultMergeBody, err := pull_service.GetDefaultMergeMessage(ctx, ctx.Repo.GitRepo, pull, mergeStyle)
|
|
||||||
if err != nil {
|
|
||||||
ctx.ServerError("GetDefaultMergeMessage", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx.Data["DefaultMergeMessage"] = defaultMergeMessage
|
|
||||||
ctx.Data["DefaultMergeBody"] = defaultMergeBody
|
|
||||||
|
|
||||||
defaultSquashMergeMessage, defaultSquashMergeBody, err := pull_service.GetDefaultMergeMessage(ctx, ctx.Repo.GitRepo, pull, repo_model.MergeStyleSquash)
|
|
||||||
if err != nil {
|
|
||||||
ctx.ServerError("GetDefaultSquashMergeMessage", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx.Data["DefaultSquashMergeMessage"] = defaultSquashMergeMessage
|
|
||||||
ctx.Data["DefaultSquashMergeBody"] = defaultSquashMergeBody
|
|
||||||
|
|
||||||
pb := prInfo.ProtectedBranchRule
|
pb := prInfo.ProtectedBranchRule
|
||||||
if pb != nil {
|
if pb != nil {
|
||||||
pb.Repo = pull.BaseRepo
|
pb.Repo = pull.BaseRepo
|
||||||
@@ -995,6 +944,9 @@ func (prInfo *pullRequestViewInfo) prepareMergeBox(ctx *context.Context, issue *
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prConfig := issue.Repo.MustGetUnit(ctx, unit.TypePullRequests).PullRequestsConfig()
|
||||||
|
data.AutodetectManualMerge = prConfig.AutodetectManualMerge
|
||||||
|
|
||||||
stillCanManualMerge := func() bool {
|
stillCanManualMerge := func() bool {
|
||||||
if pull.HasMerged || issue.IsClosed || !ctx.IsSigned {
|
if pull.HasMerged || issue.IsClosed || !ctx.IsSigned {
|
||||||
return false
|
return false
|
||||||
@@ -1007,13 +959,6 @@ func (prInfo *pullRequestViewInfo) prepareMergeBox(ctx *context.Context, issue *
|
|||||||
|
|
||||||
ctx.Data["StillCanManualMerge"] = stillCanManualMerge()
|
ctx.Data["StillCanManualMerge"] = stillCanManualMerge()
|
||||||
|
|
||||||
// Check if there is a pending pr merge
|
|
||||||
ctx.Data["HasPendingPullRequestMerge"], ctx.Data["PendingPullRequestMerge"], err = pull_model.GetScheduledMergeByPullID(ctx, pull.ID)
|
|
||||||
if err != nil {
|
|
||||||
ctx.ServerError("GetScheduledMergeByPullID", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
enableStatusCheck := pb != nil && pb.EnableStatusCheck
|
enableStatusCheck := pb != nil && pb.EnableStatusCheck
|
||||||
ctx.Data["EnableStatusCheck"] = enableStatusCheck
|
ctx.Data["EnableStatusCheck"] = enableStatusCheck
|
||||||
|
|
||||||
@@ -1043,6 +988,7 @@ func (prInfo *pullRequestViewInfo) prepareMergeBox(ctx *context.Context, issue *
|
|||||||
(!data.requireSigned || data.willSign) // signing requirement is satisfied
|
(!data.requireSigned || data.willSign) // signing requirement is satisfied
|
||||||
|
|
||||||
ctx.Data["PullMergeBoxData"] = prInfo.MergeBoxData
|
ctx.Data["PullMergeBoxData"] = prInfo.MergeBoxData
|
||||||
|
prInfo.prepareMergeBoxFormProps(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func prepareIssueViewContent(ctx *context.Context, issue *issues_model.Issue) {
|
func prepareIssueViewContent(ctx *context.Context, issue *issues_model.Issue) {
|
||||||
|
|||||||
@@ -164,12 +164,13 @@ func getPullInfo(ctx *context.Context) (issue *issues_model.Issue, ok bool) {
|
|||||||
func (prInfo *pullRequestViewInfo) setTemplateDataMergeTarget(ctx *context.Context) {
|
func (prInfo *pullRequestViewInfo) setTemplateDataMergeTarget(ctx *context.Context) {
|
||||||
pull := prInfo.issue.PullRequest
|
pull := prInfo.issue.PullRequest
|
||||||
if ctx.Repo.Owner.Name == pull.MustHeadUserName(ctx) {
|
if ctx.Repo.Owner.Name == pull.MustHeadUserName(ctx) {
|
||||||
ctx.Data["HeadTarget"] = pull.HeadBranch
|
prInfo.headTarget = pull.HeadBranch
|
||||||
} else if pull.HeadRepo == nil {
|
} else if pull.HeadRepo == nil {
|
||||||
ctx.Data["HeadTarget"] = ctx.Locale.Tr("repo.pull.deleted_branch", pull.HeadBranch)
|
prInfo.headTarget = ctx.Locale.TrString("repo.pull.deleted_branch", pull.HeadBranch)
|
||||||
} else {
|
} else {
|
||||||
ctx.Data["HeadTarget"] = pull.MustHeadUserName(ctx) + "/" + pull.HeadRepo.Name + ":" + pull.HeadBranch
|
prInfo.headTarget = pull.MustHeadUserName(ctx) + "/" + pull.HeadRepo.Name + ":" + pull.HeadBranch
|
||||||
}
|
}
|
||||||
|
ctx.Data["HeadTarget"] = prInfo.headTarget
|
||||||
ctx.Data["BaseTarget"] = pull.BaseBranch
|
ctx.Data["BaseTarget"] = pull.BaseBranch
|
||||||
headBranchLink := ""
|
headBranchLink := ""
|
||||||
if pull.Flow == issues_model.PullRequestFlowGithub {
|
if pull.Flow == issues_model.PullRequestFlowGithub {
|
||||||
@@ -268,6 +269,11 @@ type pullMergeBoxData struct {
|
|||||||
HasOverridableBlockers bool
|
HasOverridableBlockers bool
|
||||||
CanMergeNow bool
|
CanMergeNow bool
|
||||||
|
|
||||||
|
MergeFormProps map[string]any
|
||||||
|
ShowPullCommands bool
|
||||||
|
ShowMergeInstructions bool
|
||||||
|
AutodetectManualMerge bool
|
||||||
|
|
||||||
// don't expose unneeded fields to templates, need more refactoring changes
|
// don't expose unneeded fields to templates, need more refactoring changes
|
||||||
hasStatusCheckBlocker bool
|
hasStatusCheckBlocker bool
|
||||||
isPullBranchDeletable bool
|
isPullBranchDeletable bool
|
||||||
@@ -289,6 +295,7 @@ type pullRequestViewInfo struct {
|
|||||||
|
|
||||||
IsPullRequestBroken bool
|
IsPullRequestBroken bool
|
||||||
HeadBranchCommitID string
|
HeadBranchCommitID string
|
||||||
|
headTarget string // for display purpose only
|
||||||
|
|
||||||
CompareInfo git_service.CompareInfo
|
CompareInfo git_service.CompareInfo
|
||||||
ProtectedBranchRule *git_model.ProtectedBranch
|
ProtectedBranchRule *git_model.ProtectedBranch
|
||||||
|
|||||||
147
routers/web/repo/pull_merge_form.go
Normal file
147
routers/web/repo/pull_merge_form.go
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package repo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"html/template"
|
||||||
|
|
||||||
|
pull_model "code.gitea.io/gitea/models/pull"
|
||||||
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
|
"code.gitea.io/gitea/models/unit"
|
||||||
|
"code.gitea.io/gitea/modules/templates"
|
||||||
|
"code.gitea.io/gitea/services/context"
|
||||||
|
pull_service "code.gitea.io/gitea/services/pull"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (prInfo *pullRequestViewInfo) prepareMergeBoxFormProps(ctx *context.Context) {
|
||||||
|
pull := prInfo.issue.PullRequest
|
||||||
|
prConfig := ctx.Repo.Repository.MustGetUnit(ctx, unit.TypePullRequests).PullRequestsConfig()
|
||||||
|
|
||||||
|
// Check correct values and select default
|
||||||
|
var mergeStyle repo_model.MergeStyle
|
||||||
|
if prConfig.IsMergeStyleAllowed(prConfig.DefaultMergeStyle) {
|
||||||
|
mergeStyle = prConfig.DefaultMergeStyle
|
||||||
|
} else if prConfig.AllowMerge {
|
||||||
|
mergeStyle = repo_model.MergeStyleMerge
|
||||||
|
} else if prConfig.AllowRebase {
|
||||||
|
mergeStyle = repo_model.MergeStyleRebase
|
||||||
|
} else if prConfig.AllowRebaseMerge {
|
||||||
|
mergeStyle = repo_model.MergeStyleRebaseMerge
|
||||||
|
} else if prConfig.AllowSquash {
|
||||||
|
mergeStyle = repo_model.MergeStyleSquash
|
||||||
|
} else if prConfig.AllowFastForwardOnly {
|
||||||
|
mergeStyle = repo_model.MergeStyleFastForwardOnly
|
||||||
|
} else if prConfig.AllowManualMerge {
|
||||||
|
mergeStyle = repo_model.MergeStyleManuallyMerged
|
||||||
|
}
|
||||||
|
if mergeStyle == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if there is a pending pr merge
|
||||||
|
hasPendingPullRequestMerge, pendingPullRequestMerge, err := pull_model.GetScheduledMergeByPullID(ctx, pull.ID)
|
||||||
|
if err != nil {
|
||||||
|
ctx.ServerError("GetScheduledMergeByPullID", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var hasPendingPullRequestMergeTip template.HTML
|
||||||
|
if hasPendingPullRequestMerge {
|
||||||
|
createdPRMergeStr := templates.TimeSince(pendingPullRequestMerge.CreatedUnix)
|
||||||
|
hasPendingPullRequestMergeTip = ctx.Locale.Tr("repo.pulls.auto_merge_has_pending_schedule", pendingPullRequestMerge.Doer.Name, createdPRMergeStr)
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultMergeTitle, defaultMergeBody, err := pull_service.GetDefaultMergeMessage(ctx, ctx.Repo.GitRepo, pull, mergeStyle)
|
||||||
|
if err != nil {
|
||||||
|
ctx.ServerError("GetDefaultMergeMessage", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defaultSquashMergeTitle, defaultSquashMergeBody, err := pull_service.GetDefaultMergeMessage(ctx, ctx.Repo.GitRepo, pull, repo_model.MergeStyleSquash)
|
||||||
|
if err != nil {
|
||||||
|
ctx.ServerError("GetDefaultSquashMergeMessage", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var defaultSquashMergeCommitMessages string
|
||||||
|
if !prInfo.IsPullRequestBroken {
|
||||||
|
defaultSquashMergeCommitMessages = pull_service.GetSquashMergeCommitMessages(ctx, pull)
|
||||||
|
}
|
||||||
|
|
||||||
|
allOverridableChecksOk := !prInfo.MergeBoxData.HasOverridableBlockers
|
||||||
|
prInfo.MergeBoxData.MergeFormProps = map[string]any{
|
||||||
|
"baseLink": prInfo.issue.Link(),
|
||||||
|
"textCancel": ctx.Locale.Tr("cancel"),
|
||||||
|
"textDeleteBranch": ctx.Locale.Tr("repo.branch.delete", prInfo.headTarget),
|
||||||
|
"textAutoMergeButtonWhenSucceed": ctx.Locale.Tr("repo.pulls.auto_merge_button_when_succeed"),
|
||||||
|
"textAutoMergeWhenSucceed": ctx.Locale.Tr("repo.pulls.auto_merge_when_succeed"),
|
||||||
|
"textAutoMergeCancelSchedule": ctx.Locale.Tr("repo.pulls.auto_merge_cancel_schedule"),
|
||||||
|
"textClearMergeMessage": ctx.Locale.Tr("repo.pulls.clear_merge_message"),
|
||||||
|
"textClearMergeMessageHint": ctx.Locale.Tr("repo.pulls.clear_merge_message_hint"),
|
||||||
|
"textMergeCommitId": ctx.Locale.Tr("repo.pulls.merge_commit_id"),
|
||||||
|
|
||||||
|
"canMergeNow": prInfo.MergeBoxData.CanMergeNow,
|
||||||
|
"allOverridableChecksOk": allOverridableChecksOk,
|
||||||
|
"emptyCommit": pull.IsEmpty(),
|
||||||
|
"pullHeadCommitID": prInfo.CompareInfo.HeadCommitID,
|
||||||
|
"isPullBranchDeletable": prInfo.MergeBoxData.isPullBranchDeletable,
|
||||||
|
"defaultMergeStyle": mergeStyle,
|
||||||
|
"defaultDeleteBranchAfterMerge": prConfig.DefaultDeleteBranchAfterMerge,
|
||||||
|
"mergeMessageFieldPlaceHolder": ctx.Locale.Tr("repo.editor.commit_message_desc"),
|
||||||
|
"defaultMergeMessage": defaultMergeBody,
|
||||||
|
|
||||||
|
"hasPendingPullRequestMerge": hasPendingPullRequestMerge,
|
||||||
|
"hasPendingPullRequestMergeTip": hasPendingPullRequestMergeTip,
|
||||||
|
}
|
||||||
|
|
||||||
|
// if this pr can be merged now, then hide the auto merge
|
||||||
|
generalHideAutoMerge := prInfo.MergeBoxData.CanMergeNow && allOverridableChecksOk
|
||||||
|
|
||||||
|
prInfo.MergeBoxData.MergeFormProps["mergeStyles"] = []any{
|
||||||
|
map[string]any{
|
||||||
|
"name": "merge",
|
||||||
|
"allowed": prConfig.AllowMerge,
|
||||||
|
"textDoMerge": ctx.Locale.Tr("repo.pulls.merge_pull_request"),
|
||||||
|
"mergeTitleFieldText": defaultMergeTitle,
|
||||||
|
"mergeMessageFieldText": defaultMergeBody,
|
||||||
|
"hideAutoMerge": generalHideAutoMerge,
|
||||||
|
},
|
||||||
|
map[string]any{
|
||||||
|
"name": "rebase",
|
||||||
|
"allowed": prConfig.AllowRebase,
|
||||||
|
"textDoMerge": ctx.Locale.Tr("repo.pulls.rebase_merge_pull_request"),
|
||||||
|
"hideMergeMessageTexts": true,
|
||||||
|
"hideAutoMerge": generalHideAutoMerge,
|
||||||
|
},
|
||||||
|
map[string]any{
|
||||||
|
"name": "rebase-merge",
|
||||||
|
"allowed": prConfig.AllowRebaseMerge,
|
||||||
|
"textDoMerge": ctx.Locale.Tr("repo.pulls.rebase_merge_commit_pull_request"),
|
||||||
|
"mergeTitleFieldText": defaultMergeTitle,
|
||||||
|
"mergeMessageFieldText": defaultMergeBody,
|
||||||
|
"hideAutoMerge": generalHideAutoMerge,
|
||||||
|
},
|
||||||
|
map[string]any{
|
||||||
|
"name": "squash",
|
||||||
|
"allowed": prConfig.AllowSquash,
|
||||||
|
"textDoMerge": ctx.Locale.Tr("repo.pulls.squash_merge_pull_request"),
|
||||||
|
"mergeTitleFieldText": defaultSquashMergeTitle,
|
||||||
|
"mergeMessageFieldText": defaultSquashMergeCommitMessages + defaultSquashMergeBody,
|
||||||
|
"hideAutoMerge": generalHideAutoMerge,
|
||||||
|
},
|
||||||
|
map[string]any{
|
||||||
|
"name": "fast-forward-only",
|
||||||
|
"allowed": prConfig.AllowFastForwardOnly && pull.CommitsBehind == 0,
|
||||||
|
"textDoMerge": ctx.Locale.Tr("repo.pulls.fast_forward_only_merge_pull_request"),
|
||||||
|
"hideMergeMessageTexts": true,
|
||||||
|
"hideAutoMerge": generalHideAutoMerge,
|
||||||
|
},
|
||||||
|
map[string]any{
|
||||||
|
"name": "manually-merged",
|
||||||
|
"allowed": prConfig.AllowManualMerge,
|
||||||
|
"textDoMerge": ctx.Locale.Tr("repo.pulls.merge_manually"),
|
||||||
|
"hideMergeMessageTexts": true,
|
||||||
|
"hideAutoMerge": true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -208,100 +208,11 @@
|
|||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{if .AllowMerge}} {{/* user is allowed to merge */}}
|
{{if .AllowMerge}} {{/* user is allowed to merge */}}
|
||||||
{{$prUnit := .Repository.MustGetUnit ctx ctx.Consts.RepoUnitTypePullRequests}}
|
{{if $data.MergeFormProps}}
|
||||||
{{if or $prUnit.PullRequestsConfig.AllowMerge $prUnit.PullRequestsConfig.AllowRebase $prUnit.PullRequestsConfig.AllowRebaseMerge $prUnit.PullRequestsConfig.AllowSquash $prUnit.PullRequestsConfig.AllowFastForwardOnly}}
|
|
||||||
{{$hasPendingPullRequestMergeTip := ""}}
|
|
||||||
{{if .HasPendingPullRequestMerge}}
|
|
||||||
{{$createdPRMergeStr := DateUtils.TimeSince .PendingPullRequestMerge.CreatedUnix}}
|
|
||||||
{{$hasPendingPullRequestMergeTip = ctx.Locale.Tr "repo.pulls.auto_merge_has_pending_schedule" .PendingPullRequestMerge.Doer.Name $createdPRMergeStr}}
|
|
||||||
{{end}}
|
|
||||||
<div class="divider"></div>
|
<div class="divider"></div>
|
||||||
<script nonce="{{ctx.CspScriptNonce}}" type="module">
|
|
||||||
(() => {
|
|
||||||
const defaultMergeTitle = {{.DefaultMergeMessage}};
|
|
||||||
const defaultSquashMergeTitle = {{.DefaultSquashMergeMessage}};
|
|
||||||
const defaultMergeMessage = {{.DefaultMergeBody}};
|
|
||||||
const defaultSquashMergeMessage = {{.DefaultSquashMergeBody}};
|
|
||||||
const mergeForm = {
|
|
||||||
'baseLink': {{.Issue.Link}},
|
|
||||||
'textCancel': {{ctx.Locale.Tr "cancel"}},
|
|
||||||
'textDeleteBranch': {{ctx.Locale.Tr "repo.branch.delete" .HeadTarget}},
|
|
||||||
'textAutoMergeButtonWhenSucceed': {{ctx.Locale.Tr "repo.pulls.auto_merge_button_when_succeed"}},
|
|
||||||
'textAutoMergeWhenSucceed': {{ctx.Locale.Tr "repo.pulls.auto_merge_when_succeed"}},
|
|
||||||
'textAutoMergeCancelSchedule': {{ctx.Locale.Tr "repo.pulls.auto_merge_cancel_schedule"}},
|
|
||||||
'textClearMergeMessage': {{ctx.Locale.Tr "repo.pulls.clear_merge_message"}},
|
|
||||||
'textClearMergeMessageHint': {{ctx.Locale.Tr "repo.pulls.clear_merge_message_hint"}},
|
|
||||||
'textMergeCommitId': {{ctx.Locale.Tr "repo.pulls.merge_commit_id"}},
|
|
||||||
|
|
||||||
'canMergeNow': {{$canMergeNow}},
|
|
||||||
'allOverridableChecksOk': {{not $notAllOverridableChecksOk}},
|
|
||||||
'emptyCommit': {{.Issue.PullRequest.IsEmpty}},
|
|
||||||
'pullHeadCommitID': {{.PullHeadCommitID}},
|
|
||||||
'isPullBranchDeletable': {{.IsPullBranchDeletable}},
|
|
||||||
'defaultMergeStyle': {{.MergeStyle}},
|
|
||||||
'defaultDeleteBranchAfterMerge': {{$prUnit.PullRequestsConfig.DefaultDeleteBranchAfterMerge}},
|
|
||||||
'mergeMessageFieldPlaceHolder': {{ctx.Locale.Tr "repo.editor.commit_message_desc"}},
|
|
||||||
'defaultMergeMessage': defaultMergeMessage,
|
|
||||||
|
|
||||||
'hasPendingPullRequestMerge': {{.HasPendingPullRequestMerge}},
|
|
||||||
'hasPendingPullRequestMergeTip': {{$hasPendingPullRequestMergeTip}},
|
|
||||||
};
|
|
||||||
|
|
||||||
const generalHideAutoMerge = mergeForm.canMergeNow && mergeForm.allOverridableChecksOk; // if this pr can be merged now, then hide the auto merge
|
|
||||||
mergeForm['mergeStyles'] = [
|
|
||||||
{
|
|
||||||
'name': 'merge',
|
|
||||||
'allowed': {{$prUnit.PullRequestsConfig.AllowMerge}},
|
|
||||||
'textDoMerge': {{ctx.Locale.Tr "repo.pulls.merge_pull_request"}},
|
|
||||||
'mergeTitleFieldText': defaultMergeTitle,
|
|
||||||
'mergeMessageFieldText': defaultMergeMessage,
|
|
||||||
'hideAutoMerge': generalHideAutoMerge,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'name': 'rebase',
|
|
||||||
'allowed': {{$prUnit.PullRequestsConfig.AllowRebase}},
|
|
||||||
'textDoMerge': {{ctx.Locale.Tr "repo.pulls.rebase_merge_pull_request"}},
|
|
||||||
'hideMergeMessageTexts': true,
|
|
||||||
'hideAutoMerge': generalHideAutoMerge,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'name': 'rebase-merge',
|
|
||||||
'allowed': {{$prUnit.PullRequestsConfig.AllowRebaseMerge}},
|
|
||||||
'textDoMerge': {{ctx.Locale.Tr "repo.pulls.rebase_merge_commit_pull_request"}},
|
|
||||||
'mergeTitleFieldText': defaultMergeTitle,
|
|
||||||
'mergeMessageFieldText': defaultMergeMessage,
|
|
||||||
'hideAutoMerge': generalHideAutoMerge,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'name': 'squash',
|
|
||||||
'allowed': {{$prUnit.PullRequestsConfig.AllowSquash}},
|
|
||||||
'textDoMerge': {{ctx.Locale.Tr "repo.pulls.squash_merge_pull_request"}},
|
|
||||||
'mergeTitleFieldText': defaultSquashMergeTitle,
|
|
||||||
'mergeMessageFieldText': {{.GetCommitMessages}} + defaultSquashMergeMessage,
|
|
||||||
'hideAutoMerge': generalHideAutoMerge,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'name': 'fast-forward-only',
|
|
||||||
'allowed': {{and $prUnit.PullRequestsConfig.AllowFastForwardOnly (eq .Issue.PullRequest.CommitsBehind 0)}},
|
|
||||||
'textDoMerge': {{ctx.Locale.Tr "repo.pulls.fast_forward_only_merge_pull_request"}},
|
|
||||||
'hideMergeMessageTexts': true,
|
|
||||||
'hideAutoMerge': generalHideAutoMerge,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'name': 'manually-merged',
|
|
||||||
'allowed': {{$prUnit.PullRequestsConfig.AllowManualMerge}},
|
|
||||||
'textDoMerge': {{ctx.Locale.Tr "repo.pulls.merge_manually"}},
|
|
||||||
'hideMergeMessageTexts': true,
|
|
||||||
'hideAutoMerge': true,
|
|
||||||
}
|
|
||||||
];
|
|
||||||
window.config.pageData.pullRequestMergeForm = mergeForm;
|
|
||||||
})();
|
|
||||||
</script>
|
|
||||||
|
|
||||||
{{$showGeneralMergeForm = true}}
|
{{$showGeneralMergeForm = true}}
|
||||||
{{/* The merge form is a Vue component. After mounted, it has a button for choosing merge style, so make it have min-height to avoid layout shifting */}}
|
{{/* The merge form is a Vue component. After mounted, it has a button for choosing merge style, so make it have min-height to avoid layout shifting */}}
|
||||||
<div id="pull-request-merge-form" class="tw-min-h-[40px]"></div>
|
<div id="pull-request-merge-form" class="tw-min-h-[40px]" data-merge-form-props="{{JsonUtils.EncodeToString $data.MergeFormProps}}"></div>
|
||||||
{{else}}
|
{{else}}
|
||||||
{{/* no merge style was set in repo setting: not or ($prUnit.PullRequestsConfig.AllowMerge ...) */}}
|
{{/* no merge style was set in repo setting: not or ($prUnit.PullRequestsConfig.AllowMerge ...) */}}
|
||||||
<div class="divider"></div>
|
<div class="divider"></div>
|
||||||
@@ -396,8 +307,8 @@
|
|||||||
</form>
|
</form>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{if and .Issue.PullRequest.HeadRepo (not .Issue.PullRequest.HasMerged) (not .Issue.IsClosed)}}
|
{{if $data.ShowPullCommands}}
|
||||||
{{template "repo/issue/view_content/pull_merge_instruction" dict "PullRequest" .Issue.PullRequest "ShowMergeInstructions" .ShowMergeInstructions}}
|
{{template "repo/issue/view_content/pull_merge_instruction" dict "PullRequest" .Issue.PullRequest "MergeBoxData" $data}}
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,57 +1,59 @@
|
|||||||
|
{{$data := $.MergeBoxData}}
|
||||||
|
{{$pull := $.PullRequest}}
|
||||||
<div class="divider"></div>
|
<div class="divider"></div>
|
||||||
<details>
|
<details>
|
||||||
<summary>{{ctx.Locale.Tr "repo.pulls.cmd_instruction_hint"}}</summary>
|
<summary>{{ctx.Locale.Tr "repo.pulls.cmd_instruction_hint"}}</summary>
|
||||||
<div class="tw-mt-2">
|
<div class="tw-mt-2">
|
||||||
<div><h3>{{ctx.Locale.Tr "repo.pulls.cmd_instruction_checkout_title"}}</h3>{{ctx.Locale.Tr "repo.pulls.cmd_instruction_checkout_desc"}}</div>
|
<div><h3>{{ctx.Locale.Tr "repo.pulls.cmd_instruction_checkout_title"}}</h3>{{ctx.Locale.Tr "repo.pulls.cmd_instruction_checkout_desc"}}</div>
|
||||||
{{$localBranch := .PullRequest.HeadBranch}}
|
{{$localBranch := $pull.HeadBranch}}
|
||||||
{{if ne .PullRequest.HeadRepo.ID .PullRequest.BaseRepo.ID}}
|
{{if ne $pull.HeadRepo.ID $pull.BaseRepo.ID}}
|
||||||
{{$localBranch = print .PullRequest.HeadRepo.OwnerName "-" .PullRequest.HeadBranch}}
|
{{$localBranch = print $pull.HeadRepo.OwnerName "-" $pull.HeadBranch}}
|
||||||
{{end}}
|
{{end}}
|
||||||
<div class="ui secondary segment tw-font-mono">
|
<div class="ui secondary segment tw-font-mono">
|
||||||
{{$gitRemoteName := ctx.RootData.SystemConfig.Repository.GitGuideRemoteName.Value ctx}}
|
{{$gitRemoteName := ctx.RootData.SystemConfig.Repository.GitGuideRemoteName.Value ctx}}
|
||||||
{{if eq .PullRequest.Flow 0}}
|
{{if eq $pull.Flow 0}}
|
||||||
<div>git fetch -u {{if ne .PullRequest.HeadRepo.ID .PullRequest.BaseRepo.ID}}{{ctx.AppFullLink .PullRequest.HeadRepo.Link}}{{else}}{{$gitRemoteName}}{{end}} {{.PullRequest.HeadBranch}}:{{$localBranch}}</div>
|
<div>git fetch -u {{if ne $pull.HeadRepo.ID $pull.BaseRepo.ID}}{{ctx.AppFullLink $pull.HeadRepo.Link}}{{else}}{{$gitRemoteName}}{{end}} {{$pull.HeadBranch}}:{{$localBranch}}</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
<div>git fetch -u {{$gitRemoteName}} {{.PullRequest.GetGitHeadRefName}}:{{$localBranch}}</div>
|
<div>git fetch -u {{$gitRemoteName}} {{$pull.GetGitHeadRefName}}:{{$localBranch}}</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
<div>git checkout {{$localBranch}}</div>
|
<div>git checkout {{$localBranch}}</div>
|
||||||
</div>
|
</div>
|
||||||
{{if .ShowMergeInstructions}}
|
{{if $data.ShowMergeInstructions}}
|
||||||
<div>
|
<div>
|
||||||
<h3>{{ctx.Locale.Tr "repo.pulls.cmd_instruction_merge_title"}}</h3>
|
<h3>{{ctx.Locale.Tr "repo.pulls.cmd_instruction_merge_title"}}</h3>
|
||||||
{{ctx.Locale.Tr "repo.pulls.cmd_instruction_merge_desc"}}
|
{{ctx.Locale.Tr "repo.pulls.cmd_instruction_merge_desc"}}
|
||||||
{{if not .AutodetectManualMerge}}
|
{{if not $data.AutodetectManualMerge}}
|
||||||
<div>{{ctx.Locale.Tr "repo.pulls.cmd_instruction_merge_warning"}}</div>
|
<div>{{ctx.Locale.Tr "repo.pulls.cmd_instruction_merge_warning"}}</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
<div class="ui secondary segment tw-font-mono">
|
<div class="ui secondary segment tw-font-mono">
|
||||||
<div data-pull-merge-style="merge">
|
<div data-pull-merge-style="merge">
|
||||||
<div>git checkout {{.PullRequest.BaseBranch}}</div>
|
<div>git checkout {{$pull.BaseBranch}}</div>
|
||||||
<div>git merge --no-ff {{$localBranch}}</div>
|
<div>git merge --no-ff {{$localBranch}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="tw-hidden" data-pull-merge-style="rebase">
|
<div class="tw-hidden" data-pull-merge-style="rebase">
|
||||||
<div>git checkout {{.PullRequest.BaseBranch}}</div>
|
<div>git checkout {{$pull.BaseBranch}}</div>
|
||||||
<div>git merge --ff-only {{$localBranch}}</div>
|
<div>git merge --ff-only {{$localBranch}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="tw-hidden" data-pull-merge-style="rebase-merge">
|
<div class="tw-hidden" data-pull-merge-style="rebase-merge">
|
||||||
<div>git checkout {{$localBranch}}</div>
|
<div>git checkout {{$localBranch}}</div>
|
||||||
<div>git rebase {{.PullRequest.BaseBranch}}</div>
|
<div>git rebase {{$pull.BaseBranch}}</div>
|
||||||
<div>git checkout {{.PullRequest.BaseBranch}}</div>
|
<div>git checkout {{$pull.BaseBranch}}</div>
|
||||||
<div>git merge --no-ff {{$localBranch}}</div>
|
<div>git merge --no-ff {{$localBranch}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="tw-hidden" data-pull-merge-style="squash">
|
<div class="tw-hidden" data-pull-merge-style="squash">
|
||||||
<div>git checkout {{.PullRequest.BaseBranch}}</div>
|
<div>git checkout {{$pull.BaseBranch}}</div>
|
||||||
<div>git merge --squash {{$localBranch}}</div>
|
<div>git merge --squash {{$localBranch}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="tw-hidden" data-pull-merge-style="fast-forward-only">
|
<div class="tw-hidden" data-pull-merge-style="fast-forward-only">
|
||||||
<div>git checkout {{.PullRequest.BaseBranch}}</div>
|
<div>git checkout {{$pull.BaseBranch}}</div>
|
||||||
<div>git merge --ff-only {{$localBranch}}</div>
|
<div>git merge --ff-only {{$localBranch}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="tw-hidden" data-pull-merge-style="manually-merged">
|
<div class="tw-hidden" data-pull-merge-style="manually-merged">
|
||||||
<div>git checkout {{.PullRequest.BaseBranch}}</div>
|
<div>git checkout {{$pull.BaseBranch}}</div>
|
||||||
<div>git merge {{$localBranch}}</div>
|
<div>git merge {{$localBranch}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div>git push {{$gitRemoteName}} {{.PullRequest.BaseBranch}}</div>
|
<div>git push {{$gitRemoteName}} {{$pull.BaseBranch}}</div>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,9 +3,11 @@ import {computed, onMounted, onUnmounted, shallowRef, watch} from 'vue';
|
|||||||
import {SvgIcon} from '../svg.ts';
|
import {SvgIcon} from '../svg.ts';
|
||||||
import {toggleElem} from '../utils/dom.ts';
|
import {toggleElem} from '../utils/dom.ts';
|
||||||
|
|
||||||
const {pageData} = window.config;
|
const props = defineProps<{
|
||||||
|
mergeFormProps: any, // TODO: this is a huge object, need to be refactored in the future
|
||||||
|
}>();
|
||||||
|
|
||||||
const mergeForm = pageData.pullRequestMergeForm!;
|
const mergeForm = props.mergeFormProps;
|
||||||
|
|
||||||
const mergeTitleFieldValue = shallowRef('');
|
const mergeTitleFieldValue = shallowRef('');
|
||||||
const mergeMessageFieldValue = shallowRef('');
|
const mergeMessageFieldValue = shallowRef('');
|
||||||
|
|||||||
@@ -63,27 +63,10 @@ async function initRepoPullRequestMergeForm(box: HTMLElement) {
|
|||||||
const el = box.querySelector('#pull-request-merge-form');
|
const el = box.querySelector('#pull-request-merge-form');
|
||||||
if (!el) return;
|
if (!el) return;
|
||||||
|
|
||||||
|
const data = JSON.parse(el.getAttribute('data-merge-form-props')!);
|
||||||
const {default: PullRequestMergeForm} = await import('../components/PullRequestMergeForm.vue');
|
const {default: PullRequestMergeForm} = await import('../components/PullRequestMergeForm.vue');
|
||||||
const view = createApp(PullRequestMergeForm);
|
const view = createApp(PullRequestMergeForm, {mergeFormProps: data});
|
||||||
view.mount(el);
|
view.mount(el); // TODO: can unmount when reloaded?
|
||||||
}
|
|
||||||
|
|
||||||
function executeScripts(elem: Element) {
|
|
||||||
// find any existing nonce value from the current page and apply it to the new script
|
|
||||||
const scriptNonce = document.querySelector('script[nonce]')!.getAttribute('nonce')!;
|
|
||||||
for (const oldScript of elem.querySelectorAll('script')) {
|
|
||||||
// TODO: that's the only way to load the data for the merge form. In the future
|
|
||||||
// we need to completely decouple the page data and embedded script
|
|
||||||
// eslint-disable-next-line github/no-dynamic-script-tag
|
|
||||||
const newScript = document.createElement('script');
|
|
||||||
for (const attr of oldScript.attributes) {
|
|
||||||
if (attr.name === 'type' && attr.value === 'module') continue;
|
|
||||||
newScript.setAttribute(attr.name, attr.value);
|
|
||||||
}
|
|
||||||
newScript.setAttribute('nonce', scriptNonce);
|
|
||||||
newScript.text = oldScript.text;
|
|
||||||
document.body.append(newScript);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function initRepoPullMergeBox(el: HTMLElement) {
|
export function initRepoPullMergeBox(el: HTMLElement) {
|
||||||
@@ -124,7 +107,6 @@ export function initRepoPullMergeBox(el: HTMLElement) {
|
|||||||
}
|
}
|
||||||
document.removeEventListener('visibilitychange', onVisibilityChange);
|
document.removeEventListener('visibilitychange', onVisibilityChange);
|
||||||
const newElem = createElementFromHTML(await resp.text());
|
const newElem = createElementFromHTML(await resp.text());
|
||||||
executeScripts(newElem);
|
|
||||||
el.replaceWith(newElem);
|
el.replaceWith(newElem);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user