add migrate from issue.label_ids to issue_label
This commit is contained in:
		
							parent
							
								
									48f12d4ead
								
							
						
					
					
						commit
						17de3ab0a3
					
				
					 13 changed files with 286 additions and 100 deletions
				
			
		|  | @ -367,6 +367,11 @@ commits.older = Older | |||
| commits.newer = Newer | ||||
| 
 | ||||
| issues.new = New Issue | ||||
| issues.new.labels = Labels | ||||
| issues.new.clear_labels = Clear labels | ||||
| issues.new.milestone = Milestone | ||||
| issues.new.assignee = Assignee | ||||
| issues.new.no_label = No Label | ||||
| issues.create = Create Issue | ||||
| issues.new_label = New Label | ||||
| issues.new_label_placeholder = Label name... | ||||
|  |  | |||
							
								
								
									
										2
									
								
								gogs.go
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								gogs.go
									
									
									
									
									
								
							|  | @ -17,7 +17,7 @@ import ( | |||
| 	"github.com/gogits/gogs/modules/setting" | ||||
| ) | ||||
| 
 | ||||
| const APP_VER = "0.6.4.0809 Beta" | ||||
| const APP_VER = "0.6.4.0810 Beta" | ||||
| 
 | ||||
| func init() { | ||||
| 	runtime.GOMAXPROCS(runtime.NumCPU()) | ||||
|  |  | |||
|  | @ -239,6 +239,26 @@ func (err ErrRepoAlreadyExist) Error() string { | |||
| 	return fmt.Sprintf("repository already exists [uname: %d, name: %s]", err.Uname, err.Name) | ||||
| } | ||||
| 
 | ||||
| // .____          ___.          .__
 | ||||
| // |    |   _____ \_ |__   ____ |  |
 | ||||
| // |    |   \__  \ | __ \_/ __ \|  |
 | ||||
| // |    |___ / __ \| \_\ \  ___/|  |__
 | ||||
| // |_______ (____  /___  /\___  >____/
 | ||||
| //         \/    \/    \/     \/
 | ||||
| 
 | ||||
| type ErrLabelNotExist struct { | ||||
| 	ID int64 | ||||
| } | ||||
| 
 | ||||
| func IsErrLabelNotExist(err error) bool { | ||||
| 	_, ok := err.(ErrLabelNotExist) | ||||
| 	return ok | ||||
| } | ||||
| 
 | ||||
| func (err ErrLabelNotExist) Error() string { | ||||
| 	return fmt.Sprintf("label does not exist [id: %d]", err.ID) | ||||
| } | ||||
| 
 | ||||
| //    _____  .__.__                   __
 | ||||
| //   /     \ |__|  |   ____   _______/  |_  ____   ____   ____
 | ||||
| //  /  \ /  \|  |  | _/ __ \ /  ___/\   __\/  _ \ /    \_/ __ \
 | ||||
|  |  | |||
							
								
								
									
										186
									
								
								models/issue.go
									
									
									
									
									
								
							
							
						
						
									
										186
									
								
								models/issue.go
									
									
									
									
									
								
							|  | @ -7,6 +7,7 @@ package models | |||
| import ( | ||||
| 	"bytes" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"html/template" | ||||
| 	"os" | ||||
| 	"strconv" | ||||
|  | @ -22,7 +23,6 @@ import ( | |||
| 
 | ||||
| var ( | ||||
| 	ErrIssueNotExist       = errors.New("Issue does not exist") | ||||
| 	ErrLabelNotExist       = errors.New("Label does not exist") | ||||
| 	ErrWrongIssueCounter   = errors.New("Invalid number of issues for this milestone") | ||||
| 	ErrAttachmentNotExist  = errors.New("Attachment does not exist") | ||||
| 	ErrAttachmentNotLinked = errors.New("Attachment does not belong to this issue") | ||||
|  | @ -38,7 +38,6 @@ type Issue struct { | |||
| 	Repo            *Repository `xorm:"-"` | ||||
| 	PosterID        int64 | ||||
| 	Poster          *User    `xorm:"-"` | ||||
| 	LabelIDs        string   `xorm:"label_ids TEXT"` | ||||
| 	Labels          []*Label `xorm:"-"` | ||||
| 	MilestoneID     int64 | ||||
| 	Milestone       *Milestone `xorm:"-"` | ||||
|  | @ -76,29 +75,50 @@ func (i *Issue) GetPoster() (err error) { | |||
| 	return err | ||||
| } | ||||
| 
 | ||||
| func (i *Issue) GetLabels() error { | ||||
| 	if len(i.LabelIDs) < 3 { | ||||
| func (i *Issue) hasLabel(e Engine, labelID int64) bool { | ||||
| 	return hasIssueLabel(e, i.ID, labelID) | ||||
| } | ||||
| 
 | ||||
| // HasLabel returns true if issue has been labeled by given ID.
 | ||||
| func (i *Issue) HasLabel(labelID int64) bool { | ||||
| 	return i.hasLabel(x, labelID) | ||||
| } | ||||
| 
 | ||||
| func (i *Issue) addLabel(e Engine, labelID int64) error { | ||||
| 	return newIssueLabel(e, i.ID, labelID) | ||||
| } | ||||
| 
 | ||||
| // AddLabel adds new label to issue by given ID.
 | ||||
| func (i *Issue) AddLabel(labelID int64) error { | ||||
| 	return i.addLabel(x, labelID) | ||||
| } | ||||
| 
 | ||||
| func (i *Issue) getLabels(e Engine) (err error) { | ||||
| 	if len(i.Labels) > 0 { | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	strIds := strings.Split(strings.TrimSuffix(i.LabelIDs[1:], "|"), "|$") | ||||
| 	i.Labels = make([]*Label, 0, len(strIds)) | ||||
| 	for _, strId := range strIds { | ||||
| 		id := com.StrTo(strId).MustInt64() | ||||
| 		if id > 0 { | ||||
| 			l, err := GetLabelById(id) | ||||
| 			if err != nil { | ||||
| 				if err == ErrLabelNotExist { | ||||
| 					continue | ||||
| 				} | ||||
| 				return err | ||||
| 			} | ||||
| 			i.Labels = append(i.Labels, l) | ||||
| 		} | ||||
| 	i.Labels, err = getLabelsByIssueID(e, i.ID) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("getLabelsByIssueID: %v", err) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // GetLabels retrieves all labels of issue and assign to corresponding field.
 | ||||
| func (i *Issue) GetLabels() error { | ||||
| 	return i.getLabels(x) | ||||
| } | ||||
| 
 | ||||
| func (i *Issue) removeLabel(e Engine, labelID int64) error { | ||||
| 	return deleteIssueLabel(e, i.ID, labelID) | ||||
| } | ||||
| 
 | ||||
| // RemoveLabel removes a label from issue by given ID.
 | ||||
| func (i *Issue) RemoveLabel(labelID int64) error { | ||||
| 	return i.removeLabel(x, labelID) | ||||
| } | ||||
| 
 | ||||
| func (i *Issue) GetAssignee() (err error) { | ||||
| 	if i.AssigneeID == 0 { | ||||
| 		return nil | ||||
|  | @ -261,12 +281,6 @@ const ( | |||
| 	IS_CLOSE | ||||
| ) | ||||
| 
 | ||||
| // GetIssuesByLabel returns a list of issues by given label and repository.
 | ||||
| func GetIssuesByLabel(repoID, labelID int64) ([]*Issue, error) { | ||||
| 	issues := make([]*Issue, 0, 10) | ||||
| 	return issues, x.Where("repo_id=?", repoID).And("label_ids like '%$" + com.ToStr(labelID) + "|%'").Find(&issues) | ||||
| } | ||||
| 
 | ||||
| // GetIssueCountByPoster returns number of issues of repository by poster.
 | ||||
| func GetIssueCountByPoster(uid, rid int64, isClosed bool) int64 { | ||||
| 	count, _ := x.Where("repo_id=?", rid).And("poster_id=?", uid).And("is_closed=?", isClosed).Count(new(Issue)) | ||||
|  | @ -550,7 +564,7 @@ func UpdateIssueUserPairsByMentions(uids []int64, iid int64) error { | |||
| // Label represents a label of repository for issues.
 | ||||
| type Label struct { | ||||
| 	ID              int64 `xorm:"pk autoincr"` | ||||
| 	RepoId          int64 `xorm:"INDEX"` | ||||
| 	RepoID          int64 `xorm:"INDEX"` | ||||
| 	Name            string | ||||
| 	Color           string `xorm:"VARCHAR(7)"` | ||||
| 	NumIssues       int | ||||
|  | @ -570,10 +584,9 @@ func NewLabel(l *Label) error { | |||
| 	return err | ||||
| } | ||||
| 
 | ||||
| // GetLabelById returns a label by given ID.
 | ||||
| func GetLabelById(id int64) (*Label, error) { | ||||
| func getLabelByID(e Engine, id int64) (*Label, error) { | ||||
| 	if id <= 0 { | ||||
| 		return nil, ErrLabelNotExist | ||||
| 		return nil, ErrLabelNotExist{id} | ||||
| 	} | ||||
| 
 | ||||
| 	l := &Label{ID: id} | ||||
|  | @ -581,16 +594,43 @@ func GetLabelById(id int64) (*Label, error) { | |||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} else if !has { | ||||
| 		return nil, ErrLabelNotExist | ||||
| 		return nil, ErrLabelNotExist{l.ID} | ||||
| 	} | ||||
| 	return l, nil | ||||
| } | ||||
| 
 | ||||
| // GetLabels returns a list of labels of given repository ID.
 | ||||
| func GetLabels(repoId int64) ([]*Label, error) { | ||||
| // GetLabelByID returns a label by given ID.
 | ||||
| func GetLabelByID(id int64) (*Label, error) { | ||||
| 	return getLabelByID(x, id) | ||||
| } | ||||
| 
 | ||||
| // GetLabelsByRepoID returns all labels that belong to given repository by ID.
 | ||||
| func GetLabelsByRepoID(repoID int64) ([]*Label, error) { | ||||
| 	labels := make([]*Label, 0, 10) | ||||
| 	err := x.Where("repo_id=?", repoId).Find(&labels) | ||||
| 	return labels, err | ||||
| 	return labels, x.Where("repo_id=?", repoID).Find(&labels) | ||||
| } | ||||
| 
 | ||||
| func getLabelsByIssueID(e Engine, issueID int64) ([]*Label, error) { | ||||
| 	issueLabels, err := getIssueLabels(e, issueID) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("getIssueLabels: %v", err) | ||||
| 	} | ||||
| 
 | ||||
| 	var label *Label | ||||
| 	labels := make([]*Label, 0, len(issueLabels)) | ||||
| 	for idx := range issueLabels { | ||||
| 		label, err = getLabelByID(e, issueLabels[idx].LabelID) | ||||
| 		if err != nil && !IsErrLabelNotExist(err) { | ||||
| 			return nil, fmt.Errorf("getLabelByID: %v", err) | ||||
| 		} | ||||
| 		labels = append(labels, label) | ||||
| 	} | ||||
| 	return labels, nil | ||||
| } | ||||
| 
 | ||||
| // GetLabelsByIssueID returns all labels that belong to given issue by ID.
 | ||||
| func GetLabelsByIssueID(issueID int64) ([]*Label, error) { | ||||
| 	return getLabelsByIssueID(x, issueID) | ||||
| } | ||||
| 
 | ||||
| // UpdateLabel updates label information.
 | ||||
|  | @ -601,38 +641,88 @@ func UpdateLabel(l *Label) error { | |||
| 
 | ||||
| // DeleteLabel delete a label of given repository.
 | ||||
| func DeleteLabel(repoID, labelID int64) error { | ||||
| 	l, err := GetLabelById(labelID) | ||||
| 	l, err := GetLabelByID(labelID) | ||||
| 	if err != nil { | ||||
| 		if err == ErrLabelNotExist { | ||||
| 		if IsErrLabelNotExist(err) { | ||||
| 			return nil | ||||
| 		} | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	issues, err := GetIssuesByLabel(repoID, labelID) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	sess := x.NewSession() | ||||
| 	defer sessionRelease(sess) | ||||
| 	if err = sess.Begin(); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	for _, issue := range issues { | ||||
| 		issue.LabelIDs = strings.Replace(issue.LabelIDs, "$"+com.ToStr(labelID)+"|", "", -1) | ||||
| 		if _, err = sess.Id(issue.ID).AllCols().Update(issue); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if _, err = sess.Delete(l); err != nil { | ||||
| 	if _, err = x.Where("label_id=?", labelID).Delete(new(IssueLabel)); err != nil { | ||||
| 		return err | ||||
| 	} else if _, err = sess.Delete(l); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return sess.Commit() | ||||
| } | ||||
| 
 | ||||
| // .___                            .____          ___.          .__
 | ||||
| // |   | ______ ________ __   ____ |    |   _____ \_ |__   ____ |  |
 | ||||
| // |   |/  ___//  ___/  |  \_/ __ \|    |   \__  \ | __ \_/ __ \|  |
 | ||||
| // |   |\___ \ \___ \|  |  /\  ___/|    |___ / __ \| \_\ \  ___/|  |__
 | ||||
| // |___/____  >____  >____/  \___  >_______ (____  /___  /\___  >____/
 | ||||
| //          \/     \/            \/        \/    \/    \/     \/
 | ||||
| 
 | ||||
| // IssueLabel represetns an issue-lable relation.
 | ||||
| type IssueLabel struct { | ||||
| 	ID      int64 `xorm:"pk autoincr"` | ||||
| 	IssueID int64 `xorm:"UNIQUE(s)"` | ||||
| 	LabelID int64 `xorm:"UNIQUE(s)"` | ||||
| } | ||||
| 
 | ||||
| func hasIssueLabel(e Engine, issueID, labelID int64) bool { | ||||
| 	has, _ := e.Where("issue_id=? AND label_id=?", issueID, labelID).Get(new(IssueLabel)) | ||||
| 	return has | ||||
| } | ||||
| 
 | ||||
| // HasIssueLabel returns true if issue has been labeled.
 | ||||
| func HasIssueLabel(issueID, labelID int64) bool { | ||||
| 	return hasIssueLabel(x, issueID, labelID) | ||||
| } | ||||
| 
 | ||||
| func newIssueLabel(e Engine, issueID, labelID int64) error { | ||||
| 	_, err := e.Insert(&IssueLabel{ | ||||
| 		IssueID: issueID, | ||||
| 		LabelID: labelID, | ||||
| 	}) | ||||
| 	return err | ||||
| } | ||||
| 
 | ||||
| // NewIssueLabel creates a new issue-label relation.
 | ||||
| func NewIssueLabel(issueID, labelID int64) error { | ||||
| 	return newIssueLabel(x, issueID, labelID) | ||||
| } | ||||
| 
 | ||||
| func getIssueLabels(e Engine, issueID int64) ([]*IssueLabel, error) { | ||||
| 	issueLabels := make([]*IssueLabel, 0, 10) | ||||
| 	return issueLabels, e.Where("issue_id=?", issueID).Find(&issueLabels) | ||||
| } | ||||
| 
 | ||||
| // GetIssueLabels returns all issue-label relations of given issue by ID.
 | ||||
| func GetIssueLabels(issueID int64) ([]*IssueLabel, error) { | ||||
| 	return getIssueLabels(x, issueID) | ||||
| } | ||||
| 
 | ||||
| func deleteIssueLabel(e Engine, issueID, labelID int64) error { | ||||
| 	_, err := e.Delete(&IssueLabel{ | ||||
| 		IssueID: issueID, | ||||
| 		LabelID: labelID, | ||||
| 	}) | ||||
| 	return err | ||||
| } | ||||
| 
 | ||||
| // DeleteIssueLabel deletes issue-label relation.
 | ||||
| func DeleteIssueLabel(issueID, labelID int64) error { | ||||
| 	return deleteIssueLabel(x, issueID, labelID) | ||||
| } | ||||
| 
 | ||||
| //    _____  .__.__                   __
 | ||||
| //   /     \ |__|  |   ____   _______/  |_  ____   ____   ____
 | ||||
| //  /  \ /  \|  |  | _/ __ \ /  ___/\   __\/  _ \ /    \_/ __ \
 | ||||
|  |  | |||
|  | @ -58,6 +58,7 @@ var migrations = []Migration{ | |||
| 	NewMigration("generate team-repo from team", teamToTeamRepo),                 // V3 -> V4:v0.5.13
 | ||||
| 	NewMigration("fix locale file load panic", fixLocaleFileLoadPanic),           // V4 -> V5:v0.6.0
 | ||||
| 	NewMigration("trim action compare URL prefix", trimCommitActionAppUrlPrefix), // V5 -> V6:v0.6.3
 | ||||
| 	NewMigration("generate issue-label from issue", issueToIssueLabel),           // V6 -> V7:v0.6.4
 | ||||
| } | ||||
| 
 | ||||
| // Migrate database to current version
 | ||||
|  | @ -130,6 +131,9 @@ func accessToCollaboration(x *xorm.Engine) (err error) { | |||
| 
 | ||||
| 	results, err := x.Query("SELECT u.id AS `uid`, a.repo_name AS `repo`, a.mode AS `mode`, a.created as `created` FROM `access` a JOIN `user` u ON a.user_name=u.lower_name") | ||||
| 	if err != nil { | ||||
| 		if strings.Contains(err.Error(), "no such column") { | ||||
| 			return nil | ||||
| 		} | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
|  | @ -278,6 +282,9 @@ func accessRefactor(x *xorm.Engine) (err error) { | |||
| 
 | ||||
| 		results, err = x.Query("SELECT `id`,`authorize`,`repo_ids` FROM `team` WHERE org_id=? AND authorize>? ORDER BY `authorize` ASC", ownerID, int(minAccessLevel)) | ||||
| 		if err != nil { | ||||
| 			if strings.Contains(err.Error(), "no such column") { | ||||
| 				return nil | ||||
| 			} | ||||
| 			return fmt.Errorf("select teams from org: %v", err) | ||||
| 		} | ||||
| 
 | ||||
|  | @ -339,6 +346,9 @@ func teamToTeamRepo(x *xorm.Engine) error { | |||
| 
 | ||||
| 	results, err := x.Query("SELECT `id`,`org_id`,`repo_ids` FROM `team`") | ||||
| 	if err != nil { | ||||
| 		if strings.Contains(err.Error(), "no such column") { | ||||
| 			return nil | ||||
| 		} | ||||
| 		return fmt.Errorf("select teams: %v", err) | ||||
| 	} | ||||
| 	for _, team := range results { | ||||
|  | @ -369,7 +379,7 @@ func teamToTeamRepo(x *xorm.Engine) error { | |||
| 	} | ||||
| 
 | ||||
| 	if err = sess.Sync2(new(TeamRepo)); err != nil { | ||||
| 		return fmt.Errorf("sync: %v", err) | ||||
| 		return fmt.Errorf("sync2: %v", err) | ||||
| 	} else if _, err = sess.Insert(teamRepos); err != nil { | ||||
| 		return fmt.Errorf("insert team-repos: %v", err) | ||||
| 	} | ||||
|  | @ -453,3 +463,52 @@ func trimCommitActionAppUrlPrefix(x *xorm.Engine) error { | |||
| 	} | ||||
| 	return sess.Commit() | ||||
| } | ||||
| 
 | ||||
| func issueToIssueLabel(x *xorm.Engine) error { | ||||
| 	type IssueLabel struct { | ||||
| 		ID      int64 `xorm:"pk autoincr"` | ||||
| 		IssueID int64 `xorm:"UNIQUE(s)"` | ||||
| 		LabelID int64 `xorm:"UNIQUE(s)"` | ||||
| 	} | ||||
| 
 | ||||
| 	issueLabels := make([]*IssueLabel, 0, 50) | ||||
| 	results, err := x.Query("SELECT `id`,`label_ids` FROM `issue`") | ||||
| 	if err != nil { | ||||
| 		if strings.Contains(err.Error(), "no such column") { | ||||
| 			return nil | ||||
| 		} | ||||
| 		return fmt.Errorf("select issues: %v", err) | ||||
| 	} | ||||
| 	for _, issue := range results { | ||||
| 		issueID := com.StrTo(issue["id"]).MustInt64() | ||||
| 
 | ||||
| 		// Just in case legacy code can have duplicated IDs for same label.
 | ||||
| 		mark := make(map[int64]bool) | ||||
| 		for _, idStr := range strings.Split(string(issue["label_ids"]), "|") { | ||||
| 			labelID := com.StrTo(strings.TrimPrefix(idStr, "$")).MustInt64() | ||||
| 			if labelID == 0 || mark[labelID] { | ||||
| 				continue | ||||
| 			} | ||||
| 
 | ||||
| 			mark[labelID] = true | ||||
| 			issueLabels = append(issueLabels, &IssueLabel{ | ||||
| 				IssueID: issueID, | ||||
| 				LabelID: labelID, | ||||
| 			}) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	sess := x.NewSession() | ||||
| 	defer sessionRelease(sess) | ||||
| 	if err = sess.Begin(); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	if err = sess.Sync2(new(IssueLabel)); err != nil { | ||||
| 		return fmt.Errorf("sync2: %v", err) | ||||
| 	} else if _, err = sess.Insert(issueLabels); err != nil { | ||||
| 		return fmt.Errorf("insert issue-labels: %v", err) | ||||
| 	} | ||||
| 
 | ||||
| 	return sess.Commit() | ||||
| } | ||||
|  |  | |||
|  | @ -57,7 +57,8 @@ func init() { | |||
| 		new(User), new(PublicKey), new(Oauth2), new(AccessToken), | ||||
| 		new(Repository), new(DeployKey), new(Collaboration), new(Access), | ||||
| 		new(Watch), new(Star), new(Follow), new(Action), | ||||
| 		new(Issue), new(Comment), new(Attachment), new(IssueUser), new(Label), new(Milestone), | ||||
| 		new(Issue), new(Comment), new(Attachment), new(IssueUser), | ||||
| 		new(Label), new(IssueLabel), new(Milestone), | ||||
| 		new(Mirror), new(Release), new(LoginSource), new(Webhook), | ||||
| 		new(UpdateTask), new(HookTask), | ||||
| 		new(Team), new(OrgUser), new(TeamUser), new(TeamRepo), | ||||
|  |  | |||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							|  | @ -44,7 +44,7 @@ var ( | |||
| ) | ||||
| 
 | ||||
| func RetrieveLabels(ctx *middleware.Context) { | ||||
| 	labels, err := models.GetLabels(ctx.Repo.Repository.ID) | ||||
| 	labels, err := models.GetLabelsByRepoID(ctx.Repo.Repository.ID) | ||||
| 	if err != nil { | ||||
| 		ctx.Handle(500, "RetrieveLabels.GetLabels: %v", err) | ||||
| 		return | ||||
|  | @ -180,10 +180,16 @@ func NewIssue(ctx *middleware.Context) { | |||
| 	ctx.Data["IsAttachmentEnabled"] = setting.AttachmentEnabled | ||||
| 	ctx.Data["AttachmentAllowedTypes"] = setting.AttachmentAllowedTypes | ||||
| 
 | ||||
| 	// var (
 | ||||
| 	// 	repo = ctx.Repo.Repository
 | ||||
| 	// 	err  error
 | ||||
| 	// )
 | ||||
| 	var ( | ||||
| 		repo = ctx.Repo.Repository | ||||
| 		err  error | ||||
| 	) | ||||
| 	ctx.Data["Labels"], err = models.GetLabelsByRepoID(repo.ID) | ||||
| 	if err != nil { | ||||
| 		ctx.Handle(500, "GetLabelsByRepoID: %v", err) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	// // Get all milestones.
 | ||||
| 	// ctx.Data["OpenMilestones"], err = models.GetMilestones(repo.ID, -1, false)
 | ||||
| 	// if err != nil {
 | ||||
|  | @ -403,7 +409,7 @@ func ViewIssue(ctx *middleware.Context) { | |||
| 		ctx.Handle(500, "GetLabels", err) | ||||
| 		return | ||||
| 	} | ||||
| 	labels, err := models.GetLabels(ctx.Repo.Repository.ID) | ||||
| 	labels, err := models.GetLabelsByRepoID(ctx.Repo.Repository.ID) | ||||
| 	if err != nil { | ||||
| 		ctx.Handle(500, "GetLabels.2", err) | ||||
| 		return | ||||
|  | @ -560,10 +566,10 @@ func UpdateIssueLabel(ctx *middleware.Context) { | |||
| 
 | ||||
| 	isAttach := ctx.Query("action") == "attach" | ||||
| 	labelStrId := ctx.Query("id") | ||||
| 	labelId := com.StrTo(labelStrId).MustInt64() | ||||
| 	label, err := models.GetLabelById(labelId) | ||||
| 	labelID := com.StrTo(labelStrId).MustInt64() | ||||
| 	label, err := models.GetLabelByID(labelID) | ||||
| 	if err != nil { | ||||
| 		if err == models.ErrLabelNotExist { | ||||
| 		if models.IsErrLabelNotExist(err) { | ||||
| 			ctx.Handle(404, "issue.UpdateIssueLabel(GetLabelById)", err) | ||||
| 		} else { | ||||
| 			ctx.Handle(500, "issue.UpdateIssueLabel(GetLabelById)", err) | ||||
|  | @ -571,16 +577,21 @@ func UpdateIssueLabel(ctx *middleware.Context) { | |||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	isHad := strings.Contains(issue.LabelIDs, "$"+labelStrId+"|") | ||||
| 	isNeedUpdate := false | ||||
| 	if isAttach { | ||||
| 		if !isHad { | ||||
| 			issue.LabelIDs += "$" + labelStrId + "|" | ||||
| 		if !issue.HasLabel(labelID) { | ||||
| 			if err = issue.AddLabel(labelID); err != nil { | ||||
| 				ctx.Handle(500, "AddLabel", err) | ||||
| 				return | ||||
| 			} | ||||
| 			isNeedUpdate = true | ||||
| 		} | ||||
| 	} else { | ||||
| 		if isHad { | ||||
| 			issue.LabelIDs = strings.Replace(issue.LabelIDs, "$"+labelStrId+"|", "", -1) | ||||
| 		if issue.HasLabel(labelID) { | ||||
| 			if err = issue.RemoveLabel(labelID); err != nil { | ||||
| 				ctx.Handle(500, "RemoveLabel", err) | ||||
| 				return | ||||
| 			} | ||||
| 			isNeedUpdate = true | ||||
| 		} | ||||
| 	} | ||||
|  | @ -958,7 +969,7 @@ func NewLabel(ctx *middleware.Context, form auth.CreateLabelForm) { | |||
| 	} | ||||
| 
 | ||||
| 	l := &models.Label{ | ||||
| 		RepoId: ctx.Repo.Repository.ID, | ||||
| 		RepoID: ctx.Repo.Repository.ID, | ||||
| 		Name:   form.Title, | ||||
| 		Color:  form.Color, | ||||
| 	} | ||||
|  | @ -970,10 +981,10 @@ func NewLabel(ctx *middleware.Context, form auth.CreateLabelForm) { | |||
| } | ||||
| 
 | ||||
| func UpdateLabel(ctx *middleware.Context, form auth.CreateLabelForm) { | ||||
| 	l, err := models.GetLabelById(form.ID) | ||||
| 	l, err := models.GetLabelByID(form.ID) | ||||
| 	if err != nil { | ||||
| 		switch err { | ||||
| 		case models.ErrLabelNotExist: | ||||
| 		switch { | ||||
| 		case models.IsErrLabelNotExist(err): | ||||
| 			ctx.Error(404) | ||||
| 		default: | ||||
| 			ctx.Handle(500, "UpdateLabel", err) | ||||
|  |  | |||
|  | @ -1 +1 @@ | |||
| 0.6.4.0809 Beta | ||||
| 0.6.4.0810 Beta | ||||
|  | @ -28,8 +28,6 @@ | |||
| 		{{end}} | ||||
| 
 | ||||
| 		<link href="{{AppSubUrl}}/css/todc-bootstrap.min.css" rel="stylesheet" /> | ||||
|         <link href="{{AppSubUrl}}/css/datepicker3.css" rel="stylesheet" /> | ||||
|         <link href="{{AppSubUrl}}/css/bootstrap-colorpicker.min.css" rel="stylesheet" /> | ||||
| 		<link href="{{AppSubUrl}}/css/markdown.css" rel="stylesheet" /> | ||||
| 		<link href="{{AppSubUrl}}/css/gogs.css" rel="stylesheet" /> | ||||
| 
 | ||||
|  |  | |||
|  | @ -17,7 +17,7 @@ | |||
| 		  <i class="fa fa-star{{if not $.IsStaringRepo}}-o{{end}}"></i> | ||||
| 		  {{if $.IsStaringRepo}}{{$.i18n.Tr "repo.unstar"}}{{else}}{{$.i18n.Tr "repo.star"}}{{end}} <span class="num">{{.NumStars}}</span> | ||||
| 		</a> | ||||
| 		<a class="ui black basic button {{if $.IsRepositoryOwner}}poping up{{end}}" {{if not $.IsRepositoryOwner}}href="{{AppSubUrl}}/repo/fork/{{.Id}}"{{end}} {{if $.IsRepositoryOwner}}data-content="{{$.i18n.Tr "repo.fork_from_self"}}" data-position="top right"{{end}}> | ||||
| 		<a class="ui black basic button {{if $.IsRepositoryOwner}}poping up{{end}}" {{if not $.IsRepositoryOwner}}href="{{AppSubUrl}}/repo/fork/{{.ID}}"{{end}} {{if $.IsRepositoryOwner}}data-content="{{$.i18n.Tr "repo.fork_from_self"}}" data-position="top right"{{end}}> | ||||
| 		  <i class="octicon octicon-repo-forked"></i> | ||||
| 		  {{$.i18n.Tr "repo.fork"}} <span class="num">{{.NumForks}}</span> | ||||
| 		</a> | ||||
|  |  | |||
|  | @ -11,11 +11,11 @@ | |||
|             <ul id="repo-file-nav" class="clear menu menu-line"> | ||||
|                 {{if and .IsRepositoryAdmin .Repository.BaseRepo}} | ||||
|                 {{ $baseRepo := .Repository.BaseRepo}} | ||||
|                 <li> | ||||
|                 <!-- <li> | ||||
|                     <a href="{{AppSubUrl}}/{{$baseRepo.Owner.Name}}/{{$baseRepo.Name}}/compare/{{$.BaseDefaultBranch}}...{{$.Owner.Name}}:{{$.BranchName}}"> | ||||
|                         <button class="btn btn-green btn-small btn-radius" id="repo-compare-btn"><i class="octicon octicon-git-compare"></i></button> | ||||
|                     </a> | ||||
|                 </li> | ||||
|                 </li> --> | ||||
|                 {{end}} | ||||
|                 <li id="repo-branch-switch" class="down drop"> | ||||
|                     <a> | ||||
|  |  | |||
|  | @ -8,7 +8,7 @@ | |||
|   <div class="twelve wide column"> | ||||
| 		<div class="ui comments"> | ||||
| 		  <div class="comment"> | ||||
| 		    <a class="avatar"> | ||||
| 		    <a class="avatar" href="{{.SignedUser.HomeLink}}"> | ||||
| 		      <img src="{{.SignedUser.AvatarLink}}"> | ||||
| 		    </a> | ||||
| 		    <div class="ui segment content"> | ||||
|  | @ -37,17 +37,34 @@ | |||
| 		</div> | ||||
| 	</div> | ||||
| 
 | ||||
| 	{{if .IsRepositoryAdmin}} | ||||
| 	<div class="four wide column"> | ||||
| 		<div class="ui segment metas"> | ||||
| 			<div class="ui {{if .Labels}}disabled{{end}} dropdown jump item"> | ||||
| 			<div class="ui {{if not .Labels}}disabled{{end}} dropdown jump item"> | ||||
| 				<span class="text"> | ||||
| 					<strong>{{.i18n.Tr "repo.issues.new.labels"}}</strong> | ||||
| 					<span class="octicon octicon-gear"></span> | ||||
| 				</span> | ||||
|         <div class="filter menu"> | ||||
|         	<a class="item" href="#">{{.i18n.Tr "repo.issues.new.clear_labels"}}</a> | ||||
|         	{{range .Labels}} | ||||
|         	<a class="item" href="#"><span class="octicon {{if .IsChecked}}octicon-check{{end}}"></span><span class="label color" style="background-color: {{.Color}}"></span> {{.Name}}</a> | ||||
|           {{end}} | ||||
| 				</div> | ||||
| 			</div> | ||||
| 			<div class="ui list"> | ||||
| 				<span class="item {{if .SelectedLabels}}hide{{end}}">{{.i18n.Tr "repo.issues.new.no_label"}}</span> | ||||
| 			</div> | ||||
| 			<!-- <div class="ui divider"></div> | ||||
| 			<div class="ui {{if .Labels}}disabled{{end}} dropdown jump item"> | ||||
| 				<span class="text"> | ||||
| 					<strong>{{.i18n.Tr "repo.issues.new.milestone"}}</strong> | ||||
| 					<span class="octicon octicon-gear"></span> | ||||
| 				</span> | ||||
|         <div class="menu"> | ||||
|         	<a class="item" href="{{$.RepoLink}}/issues?type={{$.ViewType}}&state={{$.State}}&milestone={{$.MilestoneID}}">{{.i18n.Tr "repo.issues.filter_label_no_select"}}</a> | ||||
|         	{{range .Labels}} | ||||
|         	<a class="item" href="{{$.RepoLink}}/issues?type={{$.ViewType}}&state={{$.State}}&labels={{.ID}}&milestone={{$.MilestoneID}}"><span class="octicon {{if eq $.SelectLabels .ID}}octicon-check{{end}}"></span><span class="label color" style="background-color: {{.Color}}"></span> {{.Name}}</a> | ||||
|         	<a class="item" href="{{$.RepoLink}}/issues?type={{$.ViewType}}&state={{$.State}}&labels={{.ID}}&milestone={{$.MilestoneID}}"><span class="octicon {{if .IsChecked}}octicon-check{{end}}"></span><span class="label color" style="background-color: {{.Color}}"></span> {{.Name}}</a> | ||||
|           {{end}} | ||||
| 				</div> | ||||
| 			</div> | ||||
|  | @ -57,35 +74,20 @@ | |||
| 			<div class="ui divider"></div> | ||||
| 			<div class="ui {{if .Labels}}disabled{{end}} dropdown jump item"> | ||||
| 				<span class="text"> | ||||
| 					<strong>{{.i18n.Tr "repo.issues.new.labels"}}</strong> | ||||
| 					<strong>{{.i18n.Tr "repo.issues.new.assignee"}}</strong> | ||||
| 					<span class="octicon octicon-gear"></span> | ||||
| 				</span> | ||||
|         <div class="menu"> | ||||
|         	<a class="item" href="{{$.RepoLink}}/issues?type={{$.ViewType}}&state={{$.State}}&milestone={{$.MilestoneID}}">{{.i18n.Tr "repo.issues.filter_label_no_select"}}</a> | ||||
|         	{{range .Labels}} | ||||
|         	<a class="item" href="{{$.RepoLink}}/issues?type={{$.ViewType}}&state={{$.State}}&labels={{.ID}}&milestone={{$.MilestoneID}}"><span class="octicon {{if eq $.SelectLabels .ID}}octicon-check{{end}}"></span><span class="label color" style="background-color: {{.Color}}"></span> {{.Name}}</a> | ||||
|         	<a class="item" href="{{$.RepoLink}}/issues?type={{$.ViewType}}&state={{$.State}}&labels={{.ID}}&milestone={{$.MilestoneID}}"><span class="octicon {{if .IsChecked}}octicon-check{{end}}"></span><span class="label color" style="background-color: {{.Color}}"></span> {{.Name}}</a> | ||||
|           {{end}} | ||||
| 				</div> | ||||
| 			</div> | ||||
| 			<div class="ui list"> | ||||
| 				<span class="item">filter_label_no_select</span> | ||||
| 			</div> | ||||
| 			<div class="ui divider"></div> | ||||
| 			<div class="ui {{if .Labels}}disabled{{end}} dropdown jump item"> | ||||
| 				<span class="text"> | ||||
| 					<strong>{{.i18n.Tr "repo.issues.new.labels"}}</strong> | ||||
| 					<span class="octicon octicon-gear"></span> | ||||
| 				</span> | ||||
|         <div class="menu"> | ||||
|         	<a class="item" href="{{$.RepoLink}}/issues?type={{$.ViewType}}&state={{$.State}}&milestone={{$.MilestoneID}}">{{.i18n.Tr "repo.issues.filter_label_no_select"}}</a> | ||||
|         	{{range .Labels}} | ||||
|         	<a class="item" href="{{$.RepoLink}}/issues?type={{$.ViewType}}&state={{$.State}}&labels={{.ID}}&milestone={{$.MilestoneID}}"><span class="octicon {{if eq $.SelectLabels .ID}}octicon-check{{end}}"></span><span class="label color" style="background-color: {{.Color}}"></span> {{.Name}}</a> | ||||
|           {{end}} | ||||
| 				</div> | ||||
| 			</div> | ||||
| 			<div class="ui list"> | ||||
| 				<span class="item">filter_label_no_select</span> | ||||
| 			</div> | ||||
| 			</div> --> | ||||
| 		</div> | ||||
| 	</div> | ||||
| 	{{end}} | ||||
| </form> | ||||
		Loading…
	
		Reference in a new issue