mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-12-26 02:13:58 +01:00
Fix issues/pulls dependencies problems (#9842)
* Fix issues/pulls dependencies problems * fix swagger and api param name * fix js
This commit is contained in:
parent
0641965860
commit
f540d0ac87
8 changed files with 57 additions and 26 deletions
|
@ -138,8 +138,8 @@ func (r *Repository) CanUseTimetracker(issue *models.Issue, user *models.User) b
|
||||||
}
|
}
|
||||||
|
|
||||||
// CanCreateIssueDependencies returns whether or not a user can create dependencies.
|
// CanCreateIssueDependencies returns whether or not a user can create dependencies.
|
||||||
func (r *Repository) CanCreateIssueDependencies(user *models.User) bool {
|
func (r *Repository) CanCreateIssueDependencies(user *models.User, isPull bool) bool {
|
||||||
return r.Permission.CanWrite(models.UnitTypeIssues) && r.Repository.IsDependenciesEnabled()
|
return r.Repository.IsDependenciesEnabled() && r.Permission.CanWriteIssuesOrPulls(isPull)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCommitsCount returns cached commit count for current view
|
// GetCommitsCount returns cached commit count for current view
|
||||||
|
|
|
@ -51,6 +51,10 @@ func SearchIssues(ctx *context.APIContext) {
|
||||||
// description: repository to prioritize in the results
|
// description: repository to prioritize in the results
|
||||||
// type: integer
|
// type: integer
|
||||||
// format: int64
|
// format: int64
|
||||||
|
// - name: type
|
||||||
|
// in: query
|
||||||
|
// description: filter by type (issues / pulls) if set
|
||||||
|
// type: string
|
||||||
// responses:
|
// responses:
|
||||||
// "200":
|
// "200":
|
||||||
// "$ref": "#/responses/IssueList"
|
// "$ref": "#/responses/IssueList"
|
||||||
|
@ -128,6 +132,16 @@ func SearchIssues(ctx *context.APIContext) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var isPull util.OptionalBool
|
||||||
|
switch ctx.Query("type") {
|
||||||
|
case "pulls":
|
||||||
|
isPull = util.OptionalBoolTrue
|
||||||
|
case "issues":
|
||||||
|
isPull = util.OptionalBoolFalse
|
||||||
|
default:
|
||||||
|
isPull = util.OptionalBoolNone
|
||||||
|
}
|
||||||
|
|
||||||
// Only fetch the issues if we either don't have a keyword or the search returned issues
|
// Only fetch the issues if we either don't have a keyword or the search returned issues
|
||||||
// This would otherwise return all issues if no issues were found by the search.
|
// This would otherwise return all issues if no issues were found by the search.
|
||||||
if len(keyword) == 0 || len(issueIDs) > 0 || len(labelIDs) > 0 {
|
if len(keyword) == 0 || len(issueIDs) > 0 || len(labelIDs) > 0 {
|
||||||
|
@ -140,6 +154,7 @@ func SearchIssues(ctx *context.APIContext) {
|
||||||
LabelIDs: labelIDs,
|
LabelIDs: labelIDs,
|
||||||
SortType: "priorityrepo",
|
SortType: "priorityrepo",
|
||||||
PriorityRepoID: ctx.QueryInt64("priority_repo_id"),
|
PriorityRepoID: ctx.QueryInt64("priority_repo_id"),
|
||||||
|
IsPull: isPull,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -413,7 +413,7 @@ func CompareDiff(ctx *context.Context) {
|
||||||
|
|
||||||
if !nothingToCompare {
|
if !nothingToCompare {
|
||||||
// Setup information for new form.
|
// Setup information for new form.
|
||||||
RetrieveRepoMetas(ctx, ctx.Repo.Repository)
|
RetrieveRepoMetas(ctx, ctx.Repo.Repository, true)
|
||||||
if ctx.Written() {
|
if ctx.Written() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -343,7 +343,7 @@ func RetrieveRepoMilestonesAndAssignees(ctx *context.Context, repo *models.Repos
|
||||||
}
|
}
|
||||||
|
|
||||||
// RetrieveRepoMetas find all the meta information of a repository
|
// RetrieveRepoMetas find all the meta information of a repository
|
||||||
func RetrieveRepoMetas(ctx *context.Context, repo *models.Repository) []*models.Label {
|
func RetrieveRepoMetas(ctx *context.Context, repo *models.Repository, isPull bool) []*models.Label {
|
||||||
if !ctx.Repo.CanWrite(models.UnitTypeIssues) {
|
if !ctx.Repo.CanWrite(models.UnitTypeIssues) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -368,7 +368,7 @@ func RetrieveRepoMetas(ctx *context.Context, repo *models.Repository) []*models.
|
||||||
ctx.Data["Branches"] = brs
|
ctx.Data["Branches"] = brs
|
||||||
|
|
||||||
// Contains true if the user can create issue dependencies
|
// Contains true if the user can create issue dependencies
|
||||||
ctx.Data["CanCreateIssueDependencies"] = ctx.Repo.CanCreateIssueDependencies(ctx.User)
|
ctx.Data["CanCreateIssueDependencies"] = ctx.Repo.CanCreateIssueDependencies(ctx.User, isPull)
|
||||||
|
|
||||||
return labels
|
return labels
|
||||||
}
|
}
|
||||||
|
@ -438,7 +438,7 @@ func NewIssue(ctx *context.Context) {
|
||||||
setTemplateIfExists(ctx, issueTemplateKey, IssueTemplateCandidates)
|
setTemplateIfExists(ctx, issueTemplateKey, IssueTemplateCandidates)
|
||||||
renderAttachmentSettings(ctx)
|
renderAttachmentSettings(ctx)
|
||||||
|
|
||||||
RetrieveRepoMetas(ctx, ctx.Repo.Repository)
|
RetrieveRepoMetas(ctx, ctx.Repo.Repository, false)
|
||||||
if ctx.Written() {
|
if ctx.Written() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -453,7 +453,7 @@ func ValidateRepoMetas(ctx *context.Context, form auth.CreateIssueForm, isPull b
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
labels := RetrieveRepoMetas(ctx, ctx.Repo.Repository)
|
labels := RetrieveRepoMetas(ctx, ctx.Repo.Repository, isPull)
|
||||||
if ctx.Written() {
|
if ctx.Written() {
|
||||||
return nil, nil, 0
|
return nil, nil, 0
|
||||||
}
|
}
|
||||||
|
@ -665,6 +665,14 @@ func ViewIssue(ctx *context.Context) {
|
||||||
ctx.Data["PageIsIssueList"] = true
|
ctx.Data["PageIsIssueList"] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if issue.IsPull && !ctx.Repo.CanRead(models.UnitTypeIssues) {
|
||||||
|
ctx.Data["IssueType"] = "pulls"
|
||||||
|
} else if !issue.IsPull && !ctx.Repo.CanRead(models.UnitTypePullRequests) {
|
||||||
|
ctx.Data["IssueType"] = "issues"
|
||||||
|
} else {
|
||||||
|
ctx.Data["IssueType"] = "all"
|
||||||
|
}
|
||||||
|
|
||||||
ctx.Data["RequireHighlightJS"] = true
|
ctx.Data["RequireHighlightJS"] = true
|
||||||
ctx.Data["RequireDropzone"] = true
|
ctx.Data["RequireDropzone"] = true
|
||||||
ctx.Data["RequireTribute"] = true
|
ctx.Data["RequireTribute"] = true
|
||||||
|
@ -802,7 +810,7 @@ func ViewIssue(ctx *context.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the user can use the dependencies
|
// Check if the user can use the dependencies
|
||||||
ctx.Data["CanCreateIssueDependencies"] = ctx.Repo.CanCreateIssueDependencies(ctx.User)
|
ctx.Data["CanCreateIssueDependencies"] = ctx.Repo.CanCreateIssueDependencies(ctx.User, issue.IsPull)
|
||||||
|
|
||||||
// check if dependencies can be created across repositories
|
// check if dependencies can be created across repositories
|
||||||
ctx.Data["AllowCrossRepositoryDependencies"] = setting.Service.AllowCrossRepositoryDependencies
|
ctx.Data["AllowCrossRepositoryDependencies"] = setting.Service.AllowCrossRepositoryDependencies
|
||||||
|
|
|
@ -14,14 +14,6 @@ import (
|
||||||
|
|
||||||
// AddDependency adds new dependencies
|
// AddDependency adds new dependencies
|
||||||
func AddDependency(ctx *context.Context) {
|
func AddDependency(ctx *context.Context) {
|
||||||
// Check if the Repo is allowed to have dependencies
|
|
||||||
if !ctx.Repo.CanCreateIssueDependencies(ctx.User) {
|
|
||||||
ctx.Error(http.StatusForbidden, "CanCreateIssueDependencies")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
depID := ctx.QueryInt64("newDependency")
|
|
||||||
|
|
||||||
issueIndex := ctx.ParamsInt64("index")
|
issueIndex := ctx.ParamsInt64("index")
|
||||||
issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, issueIndex)
|
issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, issueIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -29,6 +21,14 @@ func AddDependency(ctx *context.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if the Repo is allowed to have dependencies
|
||||||
|
if !ctx.Repo.CanCreateIssueDependencies(ctx.User, issue.IsPull) {
|
||||||
|
ctx.Error(http.StatusForbidden, "CanCreateIssueDependencies")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
depID := ctx.QueryInt64("newDependency")
|
||||||
|
|
||||||
if err = issue.LoadRepo(); err != nil {
|
if err = issue.LoadRepo(); err != nil {
|
||||||
ctx.ServerError("LoadRepo", err)
|
ctx.ServerError("LoadRepo", err)
|
||||||
return
|
return
|
||||||
|
@ -73,14 +73,6 @@ func AddDependency(ctx *context.Context) {
|
||||||
|
|
||||||
// RemoveDependency removes the dependency
|
// RemoveDependency removes the dependency
|
||||||
func RemoveDependency(ctx *context.Context) {
|
func RemoveDependency(ctx *context.Context) {
|
||||||
// Check if the Repo is allowed to have dependencies
|
|
||||||
if !ctx.Repo.CanCreateIssueDependencies(ctx.User) {
|
|
||||||
ctx.Error(http.StatusForbidden, "CanCreateIssueDependencies")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
depID := ctx.QueryInt64("removeDependencyID")
|
|
||||||
|
|
||||||
issueIndex := ctx.ParamsInt64("index")
|
issueIndex := ctx.ParamsInt64("index")
|
||||||
issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, issueIndex)
|
issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, issueIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -88,6 +80,14 @@ func RemoveDependency(ctx *context.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if the Repo is allowed to have dependencies
|
||||||
|
if !ctx.Repo.CanCreateIssueDependencies(ctx.User, issue.IsPull) {
|
||||||
|
ctx.Error(http.StatusForbidden, "CanCreateIssueDependencies")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
depID := ctx.QueryInt64("removeDependencyID")
|
||||||
|
|
||||||
if err = issue.LoadRepo(); err != nil {
|
if err = issue.LoadRepo(); err != nil {
|
||||||
ctx.ServerError("LoadRepo", err)
|
ctx.ServerError("LoadRepo", err)
|
||||||
return
|
return
|
||||||
|
|
|
@ -428,6 +428,7 @@
|
||||||
<input type="hidden" id="repolink" value="{{$.RepoRelPath}}">
|
<input type="hidden" id="repolink" value="{{$.RepoRelPath}}">
|
||||||
<input type="hidden" id="repoId" value="{{.Repository.ID}}">
|
<input type="hidden" id="repoId" value="{{.Repository.ID}}">
|
||||||
<input type="hidden" id="crossRepoSearch" value="{{.AllowCrossRepositoryDependencies}}">
|
<input type="hidden" id="crossRepoSearch" value="{{.AllowCrossRepositoryDependencies}}">
|
||||||
|
<input type="hidden" id="type" value="{{.IssueType}}">
|
||||||
<!-- I know, there is probably a better way to do this -->
|
<!-- I know, there is probably a better way to do this -->
|
||||||
<input type="hidden" id="issueIndex" value="{{.Issue.Index}}"/>
|
<input type="hidden" id="issueIndex" value="{{.Issue.Index}}"/>
|
||||||
|
|
||||||
|
|
|
@ -1397,6 +1397,12 @@
|
||||||
"description": "repository to prioritize in the results",
|
"description": "repository to prioritize in the results",
|
||||||
"name": "priority_repo_id",
|
"name": "priority_repo_id",
|
||||||
"in": "query"
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "filter by type (issues / pulls) if set",
|
||||||
|
"name": "type",
|
||||||
|
"in": "query"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
|
|
|
@ -3455,9 +3455,10 @@ function initIssueList() {
|
||||||
const repolink = $('#repolink').val();
|
const repolink = $('#repolink').val();
|
||||||
const repoId = $('#repoId').val();
|
const repoId = $('#repoId').val();
|
||||||
const crossRepoSearch = $('#crossRepoSearch').val();
|
const crossRepoSearch = $('#crossRepoSearch').val();
|
||||||
let issueSearchUrl = `${suburl}/api/v1/repos/${repolink}/issues?q={query}`;
|
const tp = $('#type').val();
|
||||||
|
let issueSearchUrl = `${suburl}/api/v1/repos/${repolink}/issues?q={query}&type=${tp}`;
|
||||||
if (crossRepoSearch === 'true') {
|
if (crossRepoSearch === 'true') {
|
||||||
issueSearchUrl = `${suburl}/api/v1/repos/issues/search?q={query}&priority_repo_id=${repoId}`;
|
issueSearchUrl = `${suburl}/api/v1/repos/issues/search?q={query}&priority_repo_id=${repoId}&type=${tp}`;
|
||||||
}
|
}
|
||||||
$('#new-dependency-drop-list')
|
$('#new-dependency-drop-list')
|
||||||
.dropdown({
|
.dropdown({
|
||||||
|
|
Loading…
Reference in a new issue