mirror of
				https://codeberg.org/forgejo/forgejo.git
				synced 2025-11-04 08:21:11 +00:00 
			
		
		
		
	The JSONRedirect/JSONOK/JSONError functions were put into "Base" context incorrectly, it would cause abuse. Actually, they are for "web context" only, so, move them to the correct place. And by the way, use them to simplify old code: +75 -196
		
			
				
	
	
		
			228 lines
		
	
	
	
		
			6.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			228 lines
		
	
	
	
		
			6.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Copyright 2017 The Gitea Authors. All rights reserved.
 | 
						|
// SPDX-License-Identifier: MIT
 | 
						|
 | 
						|
package repo
 | 
						|
 | 
						|
import (
 | 
						|
	"net/http"
 | 
						|
 | 
						|
	"code.gitea.io/gitea/models/db"
 | 
						|
	issues_model "code.gitea.io/gitea/models/issues"
 | 
						|
	"code.gitea.io/gitea/models/organization"
 | 
						|
	"code.gitea.io/gitea/modules/base"
 | 
						|
	"code.gitea.io/gitea/modules/context"
 | 
						|
	"code.gitea.io/gitea/modules/label"
 | 
						|
	"code.gitea.io/gitea/modules/log"
 | 
						|
	repo_module "code.gitea.io/gitea/modules/repository"
 | 
						|
	"code.gitea.io/gitea/modules/web"
 | 
						|
	"code.gitea.io/gitea/services/forms"
 | 
						|
	issue_service "code.gitea.io/gitea/services/issue"
 | 
						|
)
 | 
						|
 | 
						|
const (
 | 
						|
	tplLabels base.TplName = "repo/issue/labels"
 | 
						|
)
 | 
						|
 | 
						|
// Labels render issue's labels page
 | 
						|
func Labels(ctx *context.Context) {
 | 
						|
	ctx.Data["Title"] = ctx.Tr("repo.labels")
 | 
						|
	ctx.Data["PageIsIssueList"] = true
 | 
						|
	ctx.Data["PageIsLabels"] = true
 | 
						|
	ctx.Data["LabelTemplateFiles"] = repo_module.LabelTemplateFiles
 | 
						|
	ctx.HTML(http.StatusOK, tplLabels)
 | 
						|
}
 | 
						|
 | 
						|
// InitializeLabels init labels for a repository
 | 
						|
func InitializeLabels(ctx *context.Context) {
 | 
						|
	form := web.GetForm(ctx).(*forms.InitializeLabelsForm)
 | 
						|
	if ctx.HasError() {
 | 
						|
		ctx.Redirect(ctx.Repo.RepoLink + "/labels")
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	if err := repo_module.InitializeLabels(ctx, ctx.Repo.Repository.ID, form.TemplateName, false); err != nil {
 | 
						|
		if label.IsErrTemplateLoad(err) {
 | 
						|
			originalErr := err.(label.ErrTemplateLoad).OriginalError
 | 
						|
			ctx.Flash.Error(ctx.Tr("repo.issues.label_templates.fail_to_load_file", form.TemplateName, originalErr))
 | 
						|
			ctx.Redirect(ctx.Repo.RepoLink + "/labels")
 | 
						|
			return
 | 
						|
		}
 | 
						|
		ctx.ServerError("InitializeLabels", err)
 | 
						|
		return
 | 
						|
	}
 | 
						|
	ctx.Redirect(ctx.Repo.RepoLink + "/labels")
 | 
						|
}
 | 
						|
 | 
						|
// RetrieveLabels find all the labels of a repository and organization
 | 
						|
func RetrieveLabels(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)
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	for _, l := range labels {
 | 
						|
		l.CalOpenIssues()
 | 
						|
	}
 | 
						|
 | 
						|
	ctx.Data["Labels"] = labels
 | 
						|
 | 
						|
	if ctx.Repo.Owner.IsOrganization() {
 | 
						|
		orgLabels, err := issues_model.GetLabelsByOrgID(ctx, ctx.Repo.Owner.ID, ctx.FormString("sort"), db.ListOptions{})
 | 
						|
		if err != nil {
 | 
						|
			ctx.ServerError("GetLabelsByOrgID", err)
 | 
						|
			return
 | 
						|
		}
 | 
						|
		for _, l := range orgLabels {
 | 
						|
			l.CalOpenOrgIssues(ctx, ctx.Repo.Repository.ID, l.ID)
 | 
						|
		}
 | 
						|
		ctx.Data["OrgLabels"] = orgLabels
 | 
						|
 | 
						|
		org, err := organization.GetOrgByName(ctx, ctx.Repo.Owner.LowerName)
 | 
						|
		if err != nil {
 | 
						|
			ctx.ServerError("GetOrgByName", err)
 | 
						|
			return
 | 
						|
		}
 | 
						|
		if ctx.Doer != nil {
 | 
						|
			ctx.Org.IsOwner, err = org.IsOwnedBy(ctx.Doer.ID)
 | 
						|
			if err != nil {
 | 
						|
				ctx.ServerError("org.IsOwnedBy", err)
 | 
						|
				return
 | 
						|
			}
 | 
						|
			ctx.Org.OrgLink = org.AsUser().OrganisationLink()
 | 
						|
			ctx.Data["IsOrganizationOwner"] = ctx.Org.IsOwner
 | 
						|
			ctx.Data["OrganizationLink"] = ctx.Org.OrgLink
 | 
						|
		}
 | 
						|
	}
 | 
						|
	ctx.Data["NumLabels"] = len(labels)
 | 
						|
	ctx.Data["SortType"] = ctx.FormString("sort")
 | 
						|
}
 | 
						|
 | 
						|
// NewLabel create new label for repository
 | 
						|
func NewLabel(ctx *context.Context) {
 | 
						|
	form := web.GetForm(ctx).(*forms.CreateLabelForm)
 | 
						|
	ctx.Data["Title"] = ctx.Tr("repo.labels")
 | 
						|
	ctx.Data["PageIsLabels"] = true
 | 
						|
 | 
						|
	if ctx.HasError() {
 | 
						|
		ctx.Flash.Error(ctx.Data["ErrorMsg"].(string))
 | 
						|
		ctx.Redirect(ctx.Repo.RepoLink + "/labels")
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	l := &issues_model.Label{
 | 
						|
		RepoID:      ctx.Repo.Repository.ID,
 | 
						|
		Name:        form.Title,
 | 
						|
		Exclusive:   form.Exclusive,
 | 
						|
		Description: form.Description,
 | 
						|
		Color:       form.Color,
 | 
						|
	}
 | 
						|
	if err := issues_model.NewLabel(ctx, l); err != nil {
 | 
						|
		ctx.ServerError("NewLabel", err)
 | 
						|
		return
 | 
						|
	}
 | 
						|
	ctx.Redirect(ctx.Repo.RepoLink + "/labels")
 | 
						|
}
 | 
						|
 | 
						|
// UpdateLabel update a label's name and color
 | 
						|
func UpdateLabel(ctx *context.Context) {
 | 
						|
	form := web.GetForm(ctx).(*forms.CreateLabelForm)
 | 
						|
	l, err := issues_model.GetLabelInRepoByID(ctx, ctx.Repo.Repository.ID, form.ID)
 | 
						|
	if err != nil {
 | 
						|
		switch {
 | 
						|
		case issues_model.IsErrRepoLabelNotExist(err):
 | 
						|
			ctx.Error(http.StatusNotFound)
 | 
						|
		default:
 | 
						|
			ctx.ServerError("UpdateLabel", err)
 | 
						|
		}
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	l.Name = form.Title
 | 
						|
	l.Exclusive = form.Exclusive
 | 
						|
	l.Description = form.Description
 | 
						|
	l.Color = form.Color
 | 
						|
	if err := issues_model.UpdateLabel(l); err != nil {
 | 
						|
		ctx.ServerError("UpdateLabel", err)
 | 
						|
		return
 | 
						|
	}
 | 
						|
	ctx.Redirect(ctx.Repo.RepoLink + "/labels")
 | 
						|
}
 | 
						|
 | 
						|
// DeleteLabel delete a label
 | 
						|
func DeleteLabel(ctx *context.Context) {
 | 
						|
	if err := issues_model.DeleteLabel(ctx.Repo.Repository.ID, ctx.FormInt64("id")); err != nil {
 | 
						|
		ctx.Flash.Error("DeleteLabel: " + err.Error())
 | 
						|
	} else {
 | 
						|
		ctx.Flash.Success(ctx.Tr("repo.issues.label_deletion_success"))
 | 
						|
	}
 | 
						|
 | 
						|
	ctx.JSONRedirect(ctx.Repo.RepoLink + "/labels")
 | 
						|
}
 | 
						|
 | 
						|
// UpdateIssueLabel change issue's labels
 | 
						|
func UpdateIssueLabel(ctx *context.Context) {
 | 
						|
	issues := getActionIssues(ctx)
 | 
						|
	if ctx.Written() {
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	switch action := ctx.FormString("action"); action {
 | 
						|
	case "clear":
 | 
						|
		for _, issue := range issues {
 | 
						|
			if err := issue_service.ClearLabels(issue, ctx.Doer); err != nil {
 | 
						|
				ctx.ServerError("ClearLabels", err)
 | 
						|
				return
 | 
						|
			}
 | 
						|
		}
 | 
						|
	case "attach", "detach", "toggle", "toggle-alt":
 | 
						|
		label, err := issues_model.GetLabelByID(ctx, ctx.FormInt64("id"))
 | 
						|
		if err != nil {
 | 
						|
			if issues_model.IsErrRepoLabelNotExist(err) {
 | 
						|
				ctx.Error(http.StatusNotFound, "GetLabelByID")
 | 
						|
			} else {
 | 
						|
				ctx.ServerError("GetLabelByID", err)
 | 
						|
			}
 | 
						|
			return
 | 
						|
		}
 | 
						|
 | 
						|
		if action == "toggle" {
 | 
						|
			// detach if any issues already have label, otherwise attach
 | 
						|
			action = "attach"
 | 
						|
			if label.ExclusiveScope() == "" {
 | 
						|
				for _, issue := range issues {
 | 
						|
					if issues_model.HasIssueLabel(ctx, issue.ID, label.ID) {
 | 
						|
						action = "detach"
 | 
						|
						break
 | 
						|
					}
 | 
						|
				}
 | 
						|
			}
 | 
						|
		} else if action == "toggle-alt" {
 | 
						|
			// always detach with alt key pressed, to be able to remove
 | 
						|
			// scoped labels
 | 
						|
			action = "detach"
 | 
						|
		}
 | 
						|
 | 
						|
		if action == "attach" {
 | 
						|
			for _, issue := range issues {
 | 
						|
				if err = issue_service.AddLabel(issue, ctx.Doer, label); err != nil {
 | 
						|
					ctx.ServerError("AddLabel", err)
 | 
						|
					return
 | 
						|
				}
 | 
						|
			}
 | 
						|
		} else {
 | 
						|
			for _, issue := range issues {
 | 
						|
				if err = issue_service.RemoveLabel(issue, ctx.Doer, label); err != nil {
 | 
						|
					ctx.ServerError("RemoveLabel", err)
 | 
						|
					return
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
	default:
 | 
						|
		log.Warn("Unrecognized action: %s", action)
 | 
						|
		ctx.Error(http.StatusInternalServerError)
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	ctx.JSONOK()
 | 
						|
}
 |