aboutsummaryrefslogtreecommitdiffstats
path: root/routers/web
diff options
context:
space:
mode:
authorwxiaoguang <wxiaoguang@gmail.com>2024-11-10 16:26:42 +0800
committerGitHub <noreply@github.com>2024-11-10 08:26:42 +0000
commit58c634b8549fb279aec72cecd6a48511803db067 (patch)
tree15f734f16ac5c4cf3a84301ec33dc968845f412b /routers/web
parentb55a31eb6a894feb5508e350ff5e9548b2531bd6 (diff)
downloadgitea-58c634b8549fb279aec72cecd6a48511803db067.tar.gz
gitea-58c634b8549fb279aec72cecd6a48511803db067.zip
Refactor sidebar label selector (#32460)
Introduce `issueSidebarLabelsData` to handle all sidebar labels related data.
Diffstat (limited to 'routers/web')
-rw-r--r--routers/web/repo/compare.go15
-rw-r--r--routers/web/repo/issue.go181
-rw-r--r--routers/web/repo/issue_label.go6
-rw-r--r--routers/web/repo/issue_label_test.go2
-rw-r--r--routers/web/web.go2
5 files changed, 113 insertions, 93 deletions
diff --git a/routers/web/repo/compare.go b/routers/web/repo/compare.go
index 3477ba36e8..9a7d3dfbf6 100644
--- a/routers/web/repo/compare.go
+++ b/routers/web/repo/compare.go
@@ -788,7 +788,11 @@ func CompareDiff(ctx *context.Context) {
if !nothingToCompare {
// Setup information for new form.
- RetrieveRepoMetas(ctx, ctx.Repo.Repository, true)
+ retrieveRepoMetasForIssueWriter(ctx, ctx.Repo.Repository, true)
+ if ctx.Written() {
+ return
+ }
+ labelsData := retrieveRepoLabels(ctx, ctx.Repo.Repository, 0, true)
if ctx.Written() {
return
}
@@ -796,6 +800,10 @@ func CompareDiff(ctx *context.Context) {
if ctx.Written() {
return
}
+ _, templateErrs := setTemplateIfExists(ctx, pullRequestTemplateKey, pullRequestTemplateCandidates, labelsData)
+ if len(templateErrs) > 0 {
+ ctx.Flash.Warning(renderErrorOfTemplates(ctx, templateErrs), true)
+ }
}
}
beforeCommitID := ctx.Data["BeforeCommitID"].(string)
@@ -808,11 +816,6 @@ func CompareDiff(ctx *context.Context) {
ctx.Data["Title"] = "Comparing " + base.ShortSha(beforeCommitID) + separator + base.ShortSha(afterCommitID)
ctx.Data["IsDiffCompare"] = true
- _, templateErrs := setTemplateIfExists(ctx, pullRequestTemplateKey, pullRequestTemplateCandidates)
-
- if len(templateErrs) > 0 {
- ctx.Flash.Warning(renderErrorOfTemplates(ctx, templateErrs), true)
- }
if content, ok := ctx.Data["content"].(string); ok && content != "" {
// If a template content is set, prepend the "content". In this case that's only
diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go
index 7fa8d428d3..a4e2fd8cea 100644
--- a/routers/web/repo/issue.go
+++ b/routers/web/repo/issue.go
@@ -870,51 +870,112 @@ func RetrieveRepoReviewers(ctx *context.Context, repo *repo_model.Repository, is
ctx.Data["IssueSidebarReviewersData"] = data
}
-// RetrieveRepoMetas find all the meta information of a repository
-func RetrieveRepoMetas(ctx *context.Context, repo *repo_model.Repository, isPull bool) []*issues_model.Label {
- if !ctx.Repo.CanWriteIssuesOrPulls(isPull) {
- return nil
+type issueSidebarLabelsData struct {
+ Repository *repo_model.Repository
+ RepoLink string
+ IssueID int64
+ IsPullRequest bool
+ AllLabels []*issues_model.Label
+ RepoLabels []*issues_model.Label
+ OrgLabels []*issues_model.Label
+ SelectedLabelIDs string
+}
+
+func makeSelectedStringIDs[KeyType, ItemType comparable](
+ allLabels []*issues_model.Label, candidateKey func(candidate *issues_model.Label) KeyType,
+ selectedItems []ItemType, selectedKey func(selected ItemType) KeyType,
+) string {
+ selectedIDSet := make(container.Set[string])
+ allLabelMap := map[KeyType]*issues_model.Label{}
+ for _, label := range allLabels {
+ allLabelMap[candidateKey(label)] = label
+ }
+ for _, item := range selectedItems {
+ if label, ok := allLabelMap[selectedKey(item)]; ok {
+ label.IsChecked = true
+ selectedIDSet.Add(strconv.FormatInt(label.ID, 10))
+ }
+ }
+ ids := selectedIDSet.Values()
+ sort.Strings(ids)
+ return strings.Join(ids, ",")
+}
+
+func (d *issueSidebarLabelsData) SetSelectedLabels(labels []*issues_model.Label) {
+ d.SelectedLabelIDs = makeSelectedStringIDs(
+ d.AllLabels, func(label *issues_model.Label) int64 { return label.ID },
+ labels, func(label *issues_model.Label) int64 { return label.ID },
+ )
+}
+
+func (d *issueSidebarLabelsData) SetSelectedLabelNames(labelNames []string) {
+ d.SelectedLabelIDs = makeSelectedStringIDs(
+ d.AllLabels, func(label *issues_model.Label) string { return strings.ToLower(label.Name) },
+ labelNames, strings.ToLower,
+ )
+}
+
+func (d *issueSidebarLabelsData) SetSelectedLabelIDs(labelIDs []int64) {
+ d.SelectedLabelIDs = makeSelectedStringIDs(
+ d.AllLabels, func(label *issues_model.Label) int64 { return label.ID },
+ labelIDs, func(labelID int64) int64 { return labelID },
+ )
+}
+
+func retrieveRepoLabels(ctx *context.Context, repo *repo_model.Repository, issueID int64, isPull bool) *issueSidebarLabelsData {
+ labelsData := &issueSidebarLabelsData{
+ Repository: repo,
+ RepoLink: ctx.Repo.RepoLink,
+ IssueID: issueID,
+ IsPullRequest: isPull,
}
+ ctx.Data["IssueSidebarLabelsData"] = labelsData
labels, err := issues_model.GetLabelsByRepoID(ctx, repo.ID, "", db.ListOptions{})
if err != nil {
ctx.ServerError("GetLabelsByRepoID", err)
return nil
}
- ctx.Data["Labels"] = labels
+ labelsData.RepoLabels = labels
+
if repo.Owner.IsOrganization() {
orgLabels, err := issues_model.GetLabelsByOrgID(ctx, repo.Owner.ID, ctx.FormString("sort"), db.ListOptions{})
if err != nil {
return nil
}
+ labelsData.OrgLabels = orgLabels
+ }
+ labelsData.AllLabels = append(labelsData.AllLabels, labelsData.RepoLabels...)
+ labelsData.AllLabels = append(labelsData.AllLabels, labelsData.OrgLabels...)
+ return labelsData
+}
- ctx.Data["OrgLabels"] = orgLabels
- labels = append(labels, orgLabels...)
+// retrieveRepoMetasForIssueWriter finds some the meta information of a repository for an issue/pr writer
+func retrieveRepoMetasForIssueWriter(ctx *context.Context, repo *repo_model.Repository, isPull bool) {
+ if !ctx.Repo.CanWriteIssuesOrPulls(isPull) {
+ return
}
RetrieveRepoMilestonesAndAssignees(ctx, repo)
if ctx.Written() {
- return nil
+ return
}
retrieveProjects(ctx, repo)
if ctx.Written() {
- return nil
+ return
}
PrepareBranchList(ctx)
if ctx.Written() {
- return nil
+ return
}
-
// Contains true if the user can create issue dependencies
ctx.Data["CanCreateIssueDependencies"] = ctx.Repo.CanCreateIssueDependencies(ctx, ctx.Doer, isPull)
-
- return labels
}
// Tries to load and set an issue template. The first return value indicates if a template was loaded.
-func setTemplateIfExists(ctx *context.Context, ctxDataKey string, possibleFiles []string) (bool, map[string]error) {
+func setTemplateIfExists(ctx *context.Context, ctxDataKey string, possibleFiles []string, labelsData *issueSidebarLabelsData) (bool, map[string]error) {
commit, err := ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultBranch)
if err != nil {
return false, nil
@@ -951,26 +1012,9 @@ func setTemplateIfExists(ctx *context.Context, ctxDataKey string, possibleFiles
ctx.Data["Fields"] = template.Fields
ctx.Data["TemplateFile"] = template.FileName
}
- labelIDs := make([]string, 0, len(template.Labels))
- if repoLabels, err := issues_model.GetLabelsByRepoID(ctx, ctx.Repo.Repository.ID, "", db.ListOptions{}); err == nil {
- ctx.Data["Labels"] = repoLabels
- if ctx.Repo.Owner.IsOrganization() {
- if orgLabels, err := issues_model.GetLabelsByOrgID(ctx, ctx.Repo.Owner.ID, ctx.FormString("sort"), db.ListOptions{}); err == nil {
- ctx.Data["OrgLabels"] = orgLabels
- repoLabels = append(repoLabels, orgLabels...)
- }
- }
- for _, metaLabel := range template.Labels {
- for _, repoLabel := range repoLabels {
- if strings.EqualFold(repoLabel.Name, metaLabel) {
- repoLabel.IsChecked = true
- labelIDs = append(labelIDs, strconv.FormatInt(repoLabel.ID, 10))
- break
- }
- }
- }
- }
+ labelsData.SetSelectedLabelNames(template.Labels)
+
selectedAssigneeIDs := make([]int64, 0, len(template.Assignees))
selectedAssigneeIDStrings := make([]string, 0, len(template.Assignees))
if userIDs, err := user_model.GetUserIDsByNames(ctx, template.Assignees, false); err == nil {
@@ -983,8 +1027,7 @@ func setTemplateIfExists(ctx *context.Context, ctxDataKey string, possibleFiles
if template.Ref != "" && !strings.HasPrefix(template.Ref, "refs/") { // Assume that the ref intended is always a branch - for tags users should use refs/tags/<ref>
template.Ref = git.BranchPrefix + template.Ref
}
- ctx.Data["HasSelectedLabel"] = len(labelIDs) > 0
- ctx.Data["label_ids"] = strings.Join(labelIDs, ",")
+
ctx.Data["HasSelectedAssignee"] = len(selectedAssigneeIDs) > 0
ctx.Data["assignee_ids"] = strings.Join(selectedAssigneeIDStrings, ",")
ctx.Data["SelectedAssigneeIDs"] = selectedAssigneeIDs
@@ -1042,8 +1085,14 @@ func NewIssue(ctx *context.Context) {
}
}
- RetrieveRepoMetas(ctx, ctx.Repo.Repository, false)
-
+ retrieveRepoMetasForIssueWriter(ctx, ctx.Repo.Repository, false)
+ if ctx.Written() {
+ return
+ }
+ labelsData := retrieveRepoLabels(ctx, ctx.Repo.Repository, 0, false)
+ if ctx.Written() {
+ return
+ }
tags, err := repo_model.GetTagNamesByRepoID(ctx, ctx.Repo.Repository.ID)
if err != nil {
ctx.ServerError("GetTagNamesByRepoID", err)
@@ -1052,7 +1101,7 @@ func NewIssue(ctx *context.Context) {
ctx.Data["Tags"] = tags
ret := issue_service.ParseTemplatesFromDefaultBranch(ctx.Repo.Repository, ctx.Repo.GitRepo)
- templateLoaded, errs := setTemplateIfExists(ctx, issueTemplateKey, IssueTemplateCandidates)
+ templateLoaded, errs := setTemplateIfExists(ctx, issueTemplateKey, IssueTemplateCandidates, labelsData)
for k, v := range errs {
ret.TemplateErrors[k] = v
}
@@ -1161,34 +1210,25 @@ func ValidateRepoMetas(ctx *context.Context, form forms.CreateIssueForm, isPull
err error
)
- labels := RetrieveRepoMetas(ctx, ctx.Repo.Repository, isPull)
+ retrieveRepoMetasForIssueWriter(ctx, ctx.Repo.Repository, isPull)
+ if ctx.Written() {
+ return ret
+ }
+ labelsData := retrieveRepoLabels(ctx, ctx.Repo.Repository, 0, isPull)
if ctx.Written() {
return ret
}
var labelIDs []int64
- hasSelected := false
// Check labels.
if len(form.LabelIDs) > 0 {
labelIDs, err = base.StringsToInt64s(strings.Split(form.LabelIDs, ","))
if err != nil {
return ret
}
- labelIDMark := make(container.Set[int64])
- labelIDMark.AddMultiple(labelIDs...)
-
- for i := range labels {
- if labelIDMark.Contains(labels[i].ID) {
- labels[i].IsChecked = true
- hasSelected = true
- }
- }
+ labelsData.SetSelectedLabelIDs(labelIDs)
}
- ctx.Data["Labels"] = labels
- ctx.Data["HasSelectedLabel"] = hasSelected
- ctx.Data["label_ids"] = form.LabelIDs
-
// Check milestone.
milestoneID := form.MilestoneID
if milestoneID > 0 {
@@ -1579,38 +1619,15 @@ func ViewIssue(ctx *context.Context) {
}
}
- // Metas.
- // Check labels.
- labelIDMark := make(container.Set[int64])
- for _, label := range issue.Labels {
- labelIDMark.Add(label.ID)
- }
- labels, err := issues_model.GetLabelsByRepoID(ctx, repo.ID, "", db.ListOptions{})
- if err != nil {
- ctx.ServerError("GetLabelsByRepoID", err)
+ retrieveRepoMetasForIssueWriter(ctx, repo, issue.IsPull)
+ if ctx.Written() {
return
}
- ctx.Data["Labels"] = labels
-
- if repo.Owner.IsOrganization() {
- orgLabels, err := issues_model.GetLabelsByOrgID(ctx, repo.Owner.ID, ctx.FormString("sort"), db.ListOptions{})
- if err != nil {
- ctx.ServerError("GetLabelsByOrgID", err)
- return
- }
- ctx.Data["OrgLabels"] = orgLabels
-
- labels = append(labels, orgLabels...)
- }
-
- hasSelected := false
- for i := range labels {
- if labelIDMark.Contains(labels[i].ID) {
- labels[i].IsChecked = true
- hasSelected = true
- }
+ labelsData := retrieveRepoLabels(ctx, repo, issue.ID, issue.IsPull)
+ if ctx.Written() {
+ return
}
- ctx.Data["HasSelectedLabel"] = hasSelected
+ labelsData.SetSelectedLabels(issue.Labels)
// Check milestone and assignee.
if ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) {
diff --git a/routers/web/repo/issue_label.go b/routers/web/repo/issue_label.go
index 81bee4dbb5..4874baaa54 100644
--- a/routers/web/repo/issue_label.go
+++ b/routers/web/repo/issue_label.go
@@ -53,11 +53,11 @@ func InitializeLabels(ctx *context.Context) {
ctx.Redirect(ctx.Repo.RepoLink + "/labels")
}
-// RetrieveLabels find all the labels of a repository and organization
-func RetrieveLabels(ctx *context.Context) {
+// RetrieveLabelsForList find all the labels of a repository and organization, it is only used by "/labels" page to list all labels
+func RetrieveLabelsForList(ctx *context.Context) {
labels, err := issues_model.GetLabelsByRepoID(ctx, ctx.Repo.Repository.ID, ctx.FormString("sort"), db.ListOptions{})
if err != nil {
- ctx.ServerError("RetrieveLabels.GetLabels", err)
+ ctx.ServerError("RetrieveLabelsForList.GetLabels", err)
return
}
diff --git a/routers/web/repo/issue_label_test.go b/routers/web/repo/issue_label_test.go
index 93fc72300b..c86a03da51 100644
--- a/routers/web/repo/issue_label_test.go
+++ b/routers/web/repo/issue_label_test.go
@@ -62,7 +62,7 @@ func TestRetrieveLabels(t *testing.T) {
contexttest.LoadUser(t, ctx, 2)
contexttest.LoadRepo(t, ctx, testCase.RepoID)
ctx.Req.Form.Set("sort", testCase.Sort)
- RetrieveLabels(ctx)
+ RetrieveLabelsForList(ctx)
assert.False(t, ctx.Written())
labels, ok := ctx.Data["Labels"].([]*issues_model.Label)
assert.True(t, ok)
diff --git a/routers/web/web.go b/routers/web/web.go
index 29dd8a8edc..907bf88f6f 100644
--- a/routers/web/web.go
+++ b/routers/web/web.go
@@ -1163,7 +1163,7 @@ func registerRoutes(m *web.Router) {
m.Get("/issues/posters", repo.IssuePosters) // it can't use {type:issues|pulls} because it would conflict with other routes like "/pulls/{index}"
m.Get("/pulls/posters", repo.PullPosters)
m.Get("/comments/{id}/attachments", repo.GetCommentAttachments)
- m.Get("/labels", repo.RetrieveLabels, repo.Labels)
+ m.Get("/labels", repo.RetrieveLabelsForList, repo.Labels)
m.Get("/milestones", repo.Milestones)
m.Get("/milestone/{id}", context.RepoRef(), repo.MilestoneIssuesAndPulls)
m.Group("/{type:issues|pulls}", func() {