Allow to archive labels (#26478)
## Archived labels This adds the structure to allow for archived labels. Archived labels are, just like closed milestones or projects, a medium to hide information without deleting it. It is especially useful if there are outdated labels that should no longer be used without deleting the label entirely. ## Changes 1. UI and API have been equipped with the support to mark a label as archived 2. The time when a label has been archived will be stored in the DB ## Outsourced for the future There's no special handling for archived labels at the moment. This will be done in the future. ## Screenshots ![image](https://github.com/go-gitea/gitea/assets/80308335/208f95cd-42e4-4ed7-9a1f-cd2050a645d4) ![image](https://github.com/go-gitea/gitea/assets/80308335/746428e0-40bb-45b3-b992-85602feb371d) Part of https://github.com/go-gitea/gitea/issues/25237 --------- Co-authored-by: delvh <dev.lh@web.de> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
parent
db7b0a1a4e
commit
cafce3b4b5
|
@ -7,6 +7,7 @@
|
||||||
exclusive: false
|
exclusive: false
|
||||||
num_issues: 2
|
num_issues: 2
|
||||||
num_closed_issues: 0
|
num_closed_issues: 0
|
||||||
|
archived_unix: 0
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 2
|
id: 2
|
||||||
|
@ -17,6 +18,7 @@
|
||||||
exclusive: false
|
exclusive: false
|
||||||
num_issues: 1
|
num_issues: 1
|
||||||
num_closed_issues: 1
|
num_closed_issues: 1
|
||||||
|
archived_unix: 0
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 3
|
id: 3
|
||||||
|
@ -27,6 +29,7 @@
|
||||||
exclusive: false
|
exclusive: false
|
||||||
num_issues: 0
|
num_issues: 0
|
||||||
num_closed_issues: 0
|
num_closed_issues: 0
|
||||||
|
archived_unix: 0
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 4
|
id: 4
|
||||||
|
@ -37,6 +40,7 @@
|
||||||
exclusive: false
|
exclusive: false
|
||||||
num_issues: 1
|
num_issues: 1
|
||||||
num_closed_issues: 0
|
num_closed_issues: 0
|
||||||
|
archived_unix: 0
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 5
|
id: 5
|
||||||
|
@ -47,6 +51,7 @@
|
||||||
exclusive: false
|
exclusive: false
|
||||||
num_issues: 0
|
num_issues: 0
|
||||||
num_closed_issues: 0
|
num_closed_issues: 0
|
||||||
|
archived_unix: 0
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 6
|
id: 6
|
||||||
|
@ -57,6 +62,7 @@
|
||||||
exclusive: false
|
exclusive: false
|
||||||
num_issues: 0
|
num_issues: 0
|
||||||
num_closed_issues: 0
|
num_closed_issues: 0
|
||||||
|
archived_unix: 0
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 7
|
id: 7
|
||||||
|
@ -67,6 +73,7 @@
|
||||||
exclusive: true
|
exclusive: true
|
||||||
num_issues: 0
|
num_issues: 0
|
||||||
num_closed_issues: 0
|
num_closed_issues: 0
|
||||||
|
archived_unix: 0
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 8
|
id: 8
|
||||||
|
@ -77,6 +84,7 @@
|
||||||
exclusive: true
|
exclusive: true
|
||||||
num_issues: 0
|
num_issues: 0
|
||||||
num_closed_issues: 0
|
num_closed_issues: 0
|
||||||
|
archived_unix: 0
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 9
|
id: 9
|
||||||
|
@ -87,3 +95,4 @@
|
||||||
exclusive: true
|
exclusive: true
|
||||||
num_issues: 0
|
num_issues: 0
|
||||||
num_closed_issues: 0
|
num_closed_issues: 0
|
||||||
|
archived_unix: 0
|
||||||
|
|
|
@ -97,6 +97,8 @@ type Label struct {
|
||||||
QueryString string `xorm:"-"`
|
QueryString string `xorm:"-"`
|
||||||
IsSelected bool `xorm:"-"`
|
IsSelected bool `xorm:"-"`
|
||||||
IsExcluded bool `xorm:"-"`
|
IsExcluded bool `xorm:"-"`
|
||||||
|
|
||||||
|
ArchivedUnix timeutil.TimeStamp `xorm:"DEFAULT NULL"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -109,6 +111,15 @@ func (l *Label) CalOpenIssues() {
|
||||||
l.NumOpenIssues = l.NumIssues - l.NumClosedIssues
|
l.NumOpenIssues = l.NumIssues - l.NumClosedIssues
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetArchived set the label as archived
|
||||||
|
func (l *Label) SetArchived(isArchived bool) {
|
||||||
|
if isArchived && l.ArchivedUnix.IsZero() {
|
||||||
|
l.ArchivedUnix = timeutil.TimeStampNow()
|
||||||
|
} else {
|
||||||
|
l.ArchivedUnix = timeutil.TimeStamp(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// CalOpenOrgIssues calculates the open issues of a label for a specific repo
|
// CalOpenOrgIssues calculates the open issues of a label for a specific repo
|
||||||
func (l *Label) CalOpenOrgIssues(ctx context.Context, repoID, labelID int64) {
|
func (l *Label) CalOpenOrgIssues(ctx context.Context, repoID, labelID int64) {
|
||||||
counts, _ := CountIssuesByRepo(ctx, &IssuesOptions{
|
counts, _ := CountIssuesByRepo(ctx, &IssuesOptions{
|
||||||
|
@ -153,6 +164,11 @@ func (l *Label) BelongsToOrg() bool {
|
||||||
return l.OrgID > 0
|
return l.OrgID > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsArchived returns true if label is an archived
|
||||||
|
func (l *Label) IsArchived() bool {
|
||||||
|
return l.ArchivedUnix > 0
|
||||||
|
}
|
||||||
|
|
||||||
// BelongsToRepo returns true if label is a repository label
|
// BelongsToRepo returns true if label is a repository label
|
||||||
func (l *Label) BelongsToRepo() bool {
|
func (l *Label) BelongsToRepo() bool {
|
||||||
return l.RepoID > 0
|
return l.RepoID > 0
|
||||||
|
@ -211,7 +227,7 @@ func UpdateLabel(l *Label) error {
|
||||||
}
|
}
|
||||||
l.Color = color
|
l.Color = color
|
||||||
|
|
||||||
return updateLabelCols(db.DefaultContext, l, "name", "description", "color", "exclusive")
|
return updateLabelCols(db.DefaultContext, l, "name", "description", "color", "exclusive", "archived_unix")
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteLabel delete a label
|
// DeleteLabel delete a label
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
repo_model "code.gitea.io/gitea/models/repo"
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
user_model "code.gitea.io/gitea/models/user"
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
|
"code.gitea.io/gitea/modules/timeutil"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
@ -259,11 +260,12 @@ func TestUpdateLabel(t *testing.T) {
|
||||||
label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1})
|
label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1})
|
||||||
// make sure update wont overwrite it
|
// make sure update wont overwrite it
|
||||||
update := &issues_model.Label{
|
update := &issues_model.Label{
|
||||||
ID: label.ID,
|
ID: label.ID,
|
||||||
Color: "#ffff00",
|
Color: "#ffff00",
|
||||||
Name: "newLabelName",
|
Name: "newLabelName",
|
||||||
Description: label.Description,
|
Description: label.Description,
|
||||||
Exclusive: false,
|
Exclusive: false,
|
||||||
|
ArchivedUnix: timeutil.TimeStamp(0),
|
||||||
}
|
}
|
||||||
label.Color = update.Color
|
label.Color = update.Color
|
||||||
label.Name = update.Name
|
label.Name = update.Name
|
||||||
|
@ -273,6 +275,7 @@ func TestUpdateLabel(t *testing.T) {
|
||||||
assert.EqualValues(t, label.Color, newLabel.Color)
|
assert.EqualValues(t, label.Color, newLabel.Color)
|
||||||
assert.EqualValues(t, label.Name, newLabel.Name)
|
assert.EqualValues(t, label.Name, newLabel.Name)
|
||||||
assert.EqualValues(t, label.Description, newLabel.Description)
|
assert.EqualValues(t, label.Description, newLabel.Description)
|
||||||
|
assert.EqualValues(t, newLabel.ArchivedUnix, 0)
|
||||||
unittest.CheckConsistencyFor(t, &issues_model.Label{}, &repo_model.Repository{})
|
unittest.CheckConsistencyFor(t, &issues_model.Label{}, &repo_model.Repository{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -522,6 +522,8 @@ var migrations = []Migration{
|
||||||
NewMigration("Drop deleted branch table", v1_21.DropDeletedBranchTable),
|
NewMigration("Drop deleted branch table", v1_21.DropDeletedBranchTable),
|
||||||
// v270 -> v271
|
// v270 -> v271
|
||||||
NewMigration("Fix PackageProperty typo", v1_21.FixPackagePropertyTypo),
|
NewMigration("Fix PackageProperty typo", v1_21.FixPackagePropertyTypo),
|
||||||
|
// v271 -> v272
|
||||||
|
NewMigration("Allow archiving labels", v1_21.AddArchivedUnixColumInLabelTable),
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCurrentDBVersion returns the current db version
|
// GetCurrentDBVersion returns the current db version
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package v1_21 //nolint
|
||||||
|
import (
|
||||||
|
"code.gitea.io/gitea/modules/timeutil"
|
||||||
|
|
||||||
|
"xorm.io/xorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
func AddArchivedUnixColumInLabelTable(x *xorm.Engine) error {
|
||||||
|
type Label struct {
|
||||||
|
ArchivedUnix timeutil.TimeStamp `xorm:"DEFAULT NULL"`
|
||||||
|
}
|
||||||
|
return x.Sync(new(Label))
|
||||||
|
}
|
|
@ -11,6 +11,8 @@ type Label struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
// example: false
|
// example: false
|
||||||
Exclusive bool `json:"exclusive"`
|
Exclusive bool `json:"exclusive"`
|
||||||
|
// example: false
|
||||||
|
IsArchived bool `json:"is_archived"`
|
||||||
// example: 00aabb
|
// example: 00aabb
|
||||||
Color string `json:"color"`
|
Color string `json:"color"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
|
@ -27,6 +29,8 @@ type CreateLabelOption struct {
|
||||||
// example: #00aabb
|
// example: #00aabb
|
||||||
Color string `json:"color" binding:"Required"`
|
Color string `json:"color" binding:"Required"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
|
// example: false
|
||||||
|
IsArchived bool `json:"is_archived"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// EditLabelOption options for editing a label
|
// EditLabelOption options for editing a label
|
||||||
|
@ -37,6 +41,8 @@ type EditLabelOption struct {
|
||||||
// example: #00aabb
|
// example: #00aabb
|
||||||
Color *string `json:"color"`
|
Color *string `json:"color"`
|
||||||
Description *string `json:"description"`
|
Description *string `json:"description"`
|
||||||
|
// example: false
|
||||||
|
IsArchived *bool `json:"is_archived"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// IssueLabelsOption a collection of labels
|
// IssueLabelsOption a collection of labels
|
||||||
|
|
|
@ -1491,6 +1491,8 @@ issues.label_title = Name
|
||||||
issues.label_description = Description
|
issues.label_description = Description
|
||||||
issues.label_color = Color
|
issues.label_color = Color
|
||||||
issues.label_exclusive = Exclusive
|
issues.label_exclusive = Exclusive
|
||||||
|
issues.label_archive = Archive Label
|
||||||
|
issues.label_archive_tooltip= Archived labels are excluded from the label search when applying labels to an issue. Existing labels on issues remain unaffected, allowing you to retire obsolete labels without losing information.
|
||||||
issues.label_exclusive_desc = Name the label <code>scope/item</code> to make it mutually exclusive with other <code>scope/</code> labels.
|
issues.label_exclusive_desc = Name the label <code>scope/item</code> to make it mutually exclusive with other <code>scope/</code> labels.
|
||||||
issues.label_exclusive_warning = Any conflicting scoped labels will be removed when editing the labels of an issue or pull request.
|
issues.label_exclusive_warning = Any conflicting scoped labels will be removed when editing the labels of an issue or pull request.
|
||||||
issues.label_count = %d labels
|
issues.label_count = %d labels
|
||||||
|
|
|
@ -209,6 +209,7 @@ func EditLabel(ctx *context.APIContext) {
|
||||||
if form.Description != nil {
|
if form.Description != nil {
|
||||||
l.Description = *form.Description
|
l.Description = *form.Description
|
||||||
}
|
}
|
||||||
|
l.SetArchived(form.IsArchived != nil && *form.IsArchived)
|
||||||
if err := issues_model.UpdateLabel(l); err != nil {
|
if err := issues_model.UpdateLabel(l); err != nil {
|
||||||
ctx.Error(http.StatusInternalServerError, "UpdateLabel", err)
|
ctx.Error(http.StatusInternalServerError, "UpdateLabel", err)
|
||||||
return
|
return
|
||||||
|
|
|
@ -151,7 +151,6 @@ func CreateLabel(ctx *context.APIContext) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
form.Color = color
|
form.Color = color
|
||||||
|
|
||||||
l := &issues_model.Label{
|
l := &issues_model.Label{
|
||||||
Name: form.Name,
|
Name: form.Name,
|
||||||
Exclusive: form.Exclusive,
|
Exclusive: form.Exclusive,
|
||||||
|
@ -159,6 +158,7 @@ func CreateLabel(ctx *context.APIContext) {
|
||||||
RepoID: ctx.Repo.Repository.ID,
|
RepoID: ctx.Repo.Repository.ID,
|
||||||
Description: form.Description,
|
Description: form.Description,
|
||||||
}
|
}
|
||||||
|
l.SetArchived(form.IsArchived)
|
||||||
if err := issues_model.NewLabel(ctx, l); err != nil {
|
if err := issues_model.NewLabel(ctx, l); err != nil {
|
||||||
ctx.Error(http.StatusInternalServerError, "NewLabel", err)
|
ctx.Error(http.StatusInternalServerError, "NewLabel", err)
|
||||||
return
|
return
|
||||||
|
@ -231,6 +231,7 @@ func EditLabel(ctx *context.APIContext) {
|
||||||
if form.Description != nil {
|
if form.Description != nil {
|
||||||
l.Description = *form.Description
|
l.Description = *form.Description
|
||||||
}
|
}
|
||||||
|
l.SetArchived(form.IsArchived != nil && *form.IsArchived)
|
||||||
if err := issues_model.UpdateLabel(l); err != nil {
|
if err := issues_model.UpdateLabel(l); err != nil {
|
||||||
ctx.Error(http.StatusInternalServerError, "UpdateLabel", err)
|
ctx.Error(http.StatusInternalServerError, "UpdateLabel", err)
|
||||||
return
|
return
|
||||||
|
|
|
@ -75,6 +75,7 @@ func UpdateLabel(ctx *context.Context) {
|
||||||
l.Exclusive = form.Exclusive
|
l.Exclusive = form.Exclusive
|
||||||
l.Description = form.Description
|
l.Description = form.Description
|
||||||
l.Color = form.Color
|
l.Color = form.Color
|
||||||
|
l.SetArchived(form.IsArchived)
|
||||||
if err := issues_model.UpdateLabel(l); err != nil {
|
if err := issues_model.UpdateLabel(l); err != nil {
|
||||||
ctx.ServerError("UpdateLabel", err)
|
ctx.ServerError("UpdateLabel", err)
|
||||||
return
|
return
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"code.gitea.io/gitea/modules/label"
|
"code.gitea.io/gitea/modules/label"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
repo_module "code.gitea.io/gitea/modules/repository"
|
repo_module "code.gitea.io/gitea/modules/repository"
|
||||||
|
"code.gitea.io/gitea/modules/timeutil"
|
||||||
"code.gitea.io/gitea/modules/web"
|
"code.gitea.io/gitea/modules/web"
|
||||||
"code.gitea.io/gitea/services/forms"
|
"code.gitea.io/gitea/services/forms"
|
||||||
issue_service "code.gitea.io/gitea/services/issue"
|
issue_service "code.gitea.io/gitea/services/issue"
|
||||||
|
@ -111,11 +112,12 @@ func NewLabel(ctx *context.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
l := &issues_model.Label{
|
l := &issues_model.Label{
|
||||||
RepoID: ctx.Repo.Repository.ID,
|
RepoID: ctx.Repo.Repository.ID,
|
||||||
Name: form.Title,
|
Name: form.Title,
|
||||||
Exclusive: form.Exclusive,
|
Exclusive: form.Exclusive,
|
||||||
Description: form.Description,
|
Description: form.Description,
|
||||||
Color: form.Color,
|
Color: form.Color,
|
||||||
|
ArchivedUnix: timeutil.TimeStamp(0),
|
||||||
}
|
}
|
||||||
if err := issues_model.NewLabel(ctx, l); err != nil {
|
if err := issues_model.NewLabel(ctx, l); err != nil {
|
||||||
ctx.ServerError("NewLabel", err)
|
ctx.ServerError("NewLabel", err)
|
||||||
|
@ -137,11 +139,12 @@ func UpdateLabel(ctx *context.Context) {
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
l.Name = form.Title
|
l.Name = form.Title
|
||||||
l.Exclusive = form.Exclusive
|
l.Exclusive = form.Exclusive
|
||||||
l.Description = form.Description
|
l.Description = form.Description
|
||||||
l.Color = form.Color
|
l.Color = form.Color
|
||||||
|
|
||||||
|
l.SetArchived(form.IsArchived)
|
||||||
if err := issues_model.UpdateLabel(l); err != nil {
|
if err := issues_model.UpdateLabel(l); err != nil {
|
||||||
ctx.ServerError("UpdateLabel", err)
|
ctx.ServerError("UpdateLabel", err)
|
||||||
return
|
return
|
||||||
|
|
|
@ -97,9 +97,10 @@ func TestUpdateLabel(t *testing.T) {
|
||||||
test.LoadUser(t, ctx, 2)
|
test.LoadUser(t, ctx, 2)
|
||||||
test.LoadRepo(t, ctx, 1)
|
test.LoadRepo(t, ctx, 1)
|
||||||
web.SetForm(ctx, &forms.CreateLabelForm{
|
web.SetForm(ctx, &forms.CreateLabelForm{
|
||||||
ID: 2,
|
ID: 2,
|
||||||
Title: "newnameforlabel",
|
Title: "newnameforlabel",
|
||||||
Color: "#abcdef",
|
Color: "#abcdef",
|
||||||
|
IsArchived: true,
|
||||||
})
|
})
|
||||||
UpdateLabel(ctx)
|
UpdateLabel(ctx)
|
||||||
assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
|
assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
|
||||||
|
|
|
@ -208,6 +208,7 @@ func ToLabel(label *issues_model.Label, repo *repo_model.Repository, org *user_m
|
||||||
Exclusive: label.Exclusive,
|
Exclusive: label.Exclusive,
|
||||||
Color: strings.TrimLeft(label.Color, "#"),
|
Color: strings.TrimLeft(label.Color, "#"),
|
||||||
Description: label.Description,
|
Description: label.Description,
|
||||||
|
IsArchived: label.IsArchived(),
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculate URL
|
// calculate URL
|
||||||
|
|
|
@ -569,6 +569,7 @@ type CreateLabelForm struct {
|
||||||
ID int64
|
ID int64
|
||||||
Title string `binding:"Required;MaxSize(50)" locale:"repo.issues.label_title"`
|
Title string `binding:"Required;MaxSize(50)" locale:"repo.issues.label_title"`
|
||||||
Exclusive bool `form:"exclusive"`
|
Exclusive bool `form:"exclusive"`
|
||||||
|
IsArchived bool `form:"is_archived"`
|
||||||
Description string `binding:"MaxSize(200)" locale:"repo.issues.label_description"`
|
Description string `binding:"MaxSize(200)" locale:"repo.issues.label_description"`
|
||||||
Color string `binding:"Required;MaxSize(7)" locale:"repo.issues.label_color"`
|
Color string `binding:"Required;MaxSize(7)" locale:"repo.issues.label_color"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,16 @@
|
||||||
<div class="desc gt-ml-2 gt-mt-3 gt-hidden label-exclusive-warning">
|
<div class="desc gt-ml-2 gt-mt-3 gt-hidden label-exclusive-warning">
|
||||||
{{svg "octicon-alert"}} {{.locale.Tr "repo.issues.label_exclusive_warning" | Safe}}
|
{{svg "octicon-alert"}} {{.locale.Tr "repo.issues.label_exclusive_warning" | Safe}}
|
||||||
</div>
|
</div>
|
||||||
|
<br>
|
||||||
|
</div>
|
||||||
|
<div class="field label-is-archived-input-field">
|
||||||
|
<div class="ui checkbox">
|
||||||
|
<input class="label-is-archived-input" name="is_archived" type="checkbox">
|
||||||
|
<label>{{.locale.Tr "repo.issues.label_archive"}}</label>
|
||||||
|
</div>
|
||||||
|
<i class="gt-ml-2" data-tooltip-content={{.locale.Tr "repo.issues.label_archive_tooltip"}}>
|
||||||
|
{{svg "octicon-info"}}
|
||||||
|
</i>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="description">{{.locale.Tr "repo.issues.label_description"}}</label>
|
<label for="description">{{.locale.Tr "repo.issues.label_description"}}</label>
|
||||||
|
|
|
@ -44,10 +44,10 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="label-operation">
|
<div class="label-operation">
|
||||||
{{if and (not $.PageIsOrgSettingsLabels) (not $.Repository.IsArchived) (or $.CanWriteIssues $.CanWritePulls)}}
|
{{if and (not $.PageIsOrgSettingsLabels) (not $.Repository.IsArchived) (or $.CanWriteIssues $.CanWritePulls)}}
|
||||||
<a class="edit-label-button" href="#" data-id="{{.ID}}" data-title="{{.Name}}" {{if .Exclusive}}data-exclusive{{end}} data-num-issues="{{.NumIssues}}" data-description="{{.Description}}" data-color={{.Color}}>{{svg "octicon-pencil"}} {{$.locale.Tr "repo.issues.label_edit"}}</a>
|
<a class="edit-label-button" href="#" data-id="{{.ID}}" data-title="{{.Name}}" {{if .Exclusive}}data-exclusive{{end}} {{if gt .ArchivedUnix 0}}data-is-archived{{end}} data-num-issues="{{.NumIssues}}" data-description="{{.Description}}" data-color={{.Color}}>{{svg "octicon-pencil"}} {{$.locale.Tr "repo.issues.label_edit"}}</a>
|
||||||
<a class="delete-button" href="#" data-url="{{$.Link}}/delete" data-id="{{.ID}}">{{svg "octicon-trash"}} {{$.locale.Tr "repo.issues.label_delete"}}</a>
|
<a class="delete-button" href="#" data-url="{{$.Link}}/delete" data-id="{{.ID}}">{{svg "octicon-trash"}} {{$.locale.Tr "repo.issues.label_delete"}}</a>
|
||||||
{{else if $.PageIsOrgSettingsLabels}}
|
{{else if $.PageIsOrgSettingsLabels}}
|
||||||
<a class="edit-label-button" href="#" data-id="{{.ID}}" data-title="{{.Name}}" {{if .Exclusive}}data-exclusive{{end}} data-num-issues="{{.NumIssues}}" data-description="{{.Description}}" data-color={{.Color}}>{{svg "octicon-pencil"}} {{$.locale.Tr "repo.issues.label_edit"}}</a>
|
<a class="edit-label-button" href="#" data-id="{{.ID}}" data-title="{{.Name}}" {{if .Exclusive}}data-exclusive{{end}} {{if gt .ArchivedUnix 0}}data-is-archived{{end}} data-num-issues="{{.NumIssues}}" data-description="{{.Description}}" data-color={{.Color}}>{{svg "octicon-pencil"}} {{$.locale.Tr "repo.issues.label_edit"}}</a>
|
||||||
<a class="delete-button" href="#" data-url="{{$.Link}}/delete" data-id="{{.ID}}">{{svg "octicon-trash"}} {{$.locale.Tr "repo.issues.label_delete"}}</a>
|
<a class="delete-button" href="#" data-url="{{$.Link}}/delete" data-id="{{.ID}}">{{svg "octicon-trash"}} {{$.locale.Tr "repo.issues.label_delete"}}</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -17057,6 +17057,11 @@
|
||||||
"x-go-name": "Exclusive",
|
"x-go-name": "Exclusive",
|
||||||
"example": false
|
"example": false
|
||||||
},
|
},
|
||||||
|
"is_archived": {
|
||||||
|
"type": "boolean",
|
||||||
|
"x-go-name": "IsArchived",
|
||||||
|
"example": false
|
||||||
|
},
|
||||||
"name": {
|
"name": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"x-go-name": "Name"
|
"x-go-name": "Name"
|
||||||
|
@ -18001,6 +18006,11 @@
|
||||||
"x-go-name": "Exclusive",
|
"x-go-name": "Exclusive",
|
||||||
"example": false
|
"example": false
|
||||||
},
|
},
|
||||||
|
"is_archived": {
|
||||||
|
"type": "boolean",
|
||||||
|
"x-go-name": "IsArchived",
|
||||||
|
"example": false
|
||||||
|
},
|
||||||
"name": {
|
"name": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"x-go-name": "Name"
|
"x-go-name": "Name"
|
||||||
|
@ -19479,6 +19489,11 @@
|
||||||
"format": "int64",
|
"format": "int64",
|
||||||
"x-go-name": "ID"
|
"x-go-name": "ID"
|
||||||
},
|
},
|
||||||
|
"is_archived": {
|
||||||
|
"type": "boolean",
|
||||||
|
"x-go-name": "IsArchived",
|
||||||
|
"example": false
|
||||||
|
},
|
||||||
"name": {
|
"name": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"x-go-name": "Name"
|
"x-go-name": "Name"
|
||||||
|
|
|
@ -36,7 +36,7 @@ export function initCompLabelEdit(selector) {
|
||||||
$('.new-label.modal').modal({
|
$('.new-label.modal').modal({
|
||||||
onApprove() {
|
onApprove() {
|
||||||
$('.new-label.form').trigger('submit');
|
$('.new-label.form').trigger('submit');
|
||||||
}
|
},
|
||||||
}).modal('show');
|
}).modal('show');
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
@ -49,6 +49,9 @@ export function initCompLabelEdit(selector) {
|
||||||
const nameInput = $('.edit-label .label-name-input');
|
const nameInput = $('.edit-label .label-name-input');
|
||||||
nameInput.val($(this).data('title'));
|
nameInput.val($(this).data('title'));
|
||||||
|
|
||||||
|
const isArchivedCheckbox = $('.edit-label .label-is-archived-input');
|
||||||
|
isArchivedCheckbox.prop('checked', this.hasAttribute('data-is-archived'));
|
||||||
|
|
||||||
const exclusiveCheckbox = $('.edit-label .label-exclusive-input');
|
const exclusiveCheckbox = $('.edit-label .label-exclusive-input');
|
||||||
exclusiveCheckbox.prop('checked', this.hasAttribute('data-exclusive'));
|
exclusiveCheckbox.prop('checked', this.hasAttribute('data-exclusive'));
|
||||||
// Warn when label was previously not exclusive and used in issues
|
// Warn when label was previously not exclusive and used in issues
|
||||||
|
@ -64,7 +67,7 @@ export function initCompLabelEdit(selector) {
|
||||||
$('.edit-label.modal').modal({
|
$('.edit-label.modal').modal({
|
||||||
onApprove() {
|
onApprove() {
|
||||||
$('.edit-label.form').trigger('submit');
|
$('.edit-label.form').trigger('submit');
|
||||||
}
|
},
|
||||||
}).modal('show');
|
}).modal('show');
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue