mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 10:56:10 +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:
		| @@ -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({ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user