mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 08:30:25 +08: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:
		@@ -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.
 | 
			
		||||
func (r *Repository) CanCreateIssueDependencies(user *models.User) bool {
 | 
			
		||||
	return r.Permission.CanWrite(models.UnitTypeIssues) && r.Repository.IsDependenciesEnabled()
 | 
			
		||||
func (r *Repository) CanCreateIssueDependencies(user *models.User, isPull bool) bool {
 | 
			
		||||
	return r.Repository.IsDependenciesEnabled() && r.Permission.CanWriteIssuesOrPulls(isPull)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetCommitsCount returns cached commit count for current view
 | 
			
		||||
 
 | 
			
		||||
@@ -51,6 +51,10 @@ func SearchIssues(ctx *context.APIContext) {
 | 
			
		||||
	//   description: repository to prioritize in the results
 | 
			
		||||
	//   type: integer
 | 
			
		||||
	//   format: int64
 | 
			
		||||
	// - name: type
 | 
			
		||||
	//   in: query
 | 
			
		||||
	//   description: filter by type (issues / pulls) if set
 | 
			
		||||
	//   type: string
 | 
			
		||||
	// responses:
 | 
			
		||||
	//   "200":
 | 
			
		||||
	//     "$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
 | 
			
		||||
	// This would otherwise return all issues if no issues were found by the search.
 | 
			
		||||
	if len(keyword) == 0 || len(issueIDs) > 0 || len(labelIDs) > 0 {
 | 
			
		||||
@@ -140,6 +154,7 @@ func SearchIssues(ctx *context.APIContext) {
 | 
			
		||||
			LabelIDs:       labelIDs,
 | 
			
		||||
			SortType:       "priorityrepo",
 | 
			
		||||
			PriorityRepoID: ctx.QueryInt64("priority_repo_id"),
 | 
			
		||||
			IsPull:         isPull,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -413,7 +413,7 @@ func CompareDiff(ctx *context.Context) {
 | 
			
		||||
 | 
			
		||||
		if !nothingToCompare {
 | 
			
		||||
			// Setup information for new form.
 | 
			
		||||
			RetrieveRepoMetas(ctx, ctx.Repo.Repository)
 | 
			
		||||
			RetrieveRepoMetas(ctx, ctx.Repo.Repository, true)
 | 
			
		||||
			if ctx.Written() {
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
 
 | 
			
		||||
@@ -343,7 +343,7 @@ func RetrieveRepoMilestonesAndAssignees(ctx *context.Context, repo *models.Repos
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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) {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
@@ -368,7 +368,7 @@ func RetrieveRepoMetas(ctx *context.Context, repo *models.Repository) []*models.
 | 
			
		||||
	ctx.Data["Branches"] = brs
 | 
			
		||||
 | 
			
		||||
	// 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
 | 
			
		||||
}
 | 
			
		||||
@@ -438,7 +438,7 @@ func NewIssue(ctx *context.Context) {
 | 
			
		||||
	setTemplateIfExists(ctx, issueTemplateKey, IssueTemplateCandidates)
 | 
			
		||||
	renderAttachmentSettings(ctx)
 | 
			
		||||
 | 
			
		||||
	RetrieveRepoMetas(ctx, ctx.Repo.Repository)
 | 
			
		||||
	RetrieveRepoMetas(ctx, ctx.Repo.Repository, false)
 | 
			
		||||
	if ctx.Written() {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
@@ -453,7 +453,7 @@ func ValidateRepoMetas(ctx *context.Context, form auth.CreateIssueForm, isPull b
 | 
			
		||||
		err  error
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	labels := RetrieveRepoMetas(ctx, ctx.Repo.Repository)
 | 
			
		||||
	labels := RetrieveRepoMetas(ctx, ctx.Repo.Repository, isPull)
 | 
			
		||||
	if ctx.Written() {
 | 
			
		||||
		return nil, nil, 0
 | 
			
		||||
	}
 | 
			
		||||
@@ -665,6 +665,14 @@ func ViewIssue(ctx *context.Context) {
 | 
			
		||||
		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["RequireDropzone"] = true
 | 
			
		||||
	ctx.Data["RequireTribute"] = true
 | 
			
		||||
@@ -802,7 +810,7 @@ func ViewIssue(ctx *context.Context) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 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
 | 
			
		||||
	ctx.Data["AllowCrossRepositoryDependencies"] = setting.Service.AllowCrossRepositoryDependencies
 | 
			
		||||
 
 | 
			
		||||
@@ -14,14 +14,6 @@ import (
 | 
			
		||||
 | 
			
		||||
// AddDependency adds new dependencies
 | 
			
		||||
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")
 | 
			
		||||
	issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, issueIndex)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
@@ -29,6 +21,14 @@ func AddDependency(ctx *context.Context) {
 | 
			
		||||
		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 {
 | 
			
		||||
		ctx.ServerError("LoadRepo", err)
 | 
			
		||||
		return
 | 
			
		||||
@@ -73,14 +73,6 @@ func AddDependency(ctx *context.Context) {
 | 
			
		||||
 | 
			
		||||
// RemoveDependency removes the dependency
 | 
			
		||||
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")
 | 
			
		||||
	issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, issueIndex)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
@@ -88,6 +80,14 @@ func RemoveDependency(ctx *context.Context) {
 | 
			
		||||
		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 {
 | 
			
		||||
		ctx.ServerError("LoadRepo", err)
 | 
			
		||||
		return
 | 
			
		||||
 
 | 
			
		||||
@@ -428,6 +428,7 @@
 | 
			
		||||
	<input type="hidden" id="repolink" value="{{$.RepoRelPath}}">
 | 
			
		||||
	<input type="hidden" id="repoId" value="{{.Repository.ID}}">
 | 
			
		||||
	<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 -->
 | 
			
		||||
	<input type="hidden" id="issueIndex" value="{{.Issue.Index}}"/>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1397,6 +1397,12 @@
 | 
			
		||||
            "description": "repository to prioritize in the results",
 | 
			
		||||
            "name": "priority_repo_id",
 | 
			
		||||
            "in": "query"
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            "type": "string",
 | 
			
		||||
            "description": "filter by type (issues / pulls) if set",
 | 
			
		||||
            "name": "type",
 | 
			
		||||
            "in": "query"
 | 
			
		||||
          }
 | 
			
		||||
        ],
 | 
			
		||||
        "responses": {
 | 
			
		||||
 
 | 
			
		||||
@@ -3455,9 +3455,10 @@ function initIssueList() {
 | 
			
		||||
  const repolink = $('#repolink').val();
 | 
			
		||||
  const repoId = $('#repoId').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') {
 | 
			
		||||
    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')
 | 
			
		||||
    .dropdown({
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user