* Fix issues/pulls dependencies problems * fix swagger and api param name * fix jstags/v1.21.12.1
| @@ -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({ | |||