Added basic functionality:
* Add new dependecy * Show dependencies Signed-off-by: Konrad <konrad@kola-entertainments.de>
This commit is contained in:
parent
0a4925fb17
commit
cf7e99fc4c
|
|
@ -379,7 +379,7 @@ MODE = console
|
||||||
; Buffer length of channel, keep it as it is if you don't know what it is.
|
; Buffer length of channel, keep it as it is if you don't know what it is.
|
||||||
BUFFER_LEN = 10000
|
BUFFER_LEN = 10000
|
||||||
; Either "Trace", "Debug", "Info", "Warn", "Error", "Critical", default is "Trace"
|
; Either "Trace", "Debug", "Info", "Warn", "Error", "Critical", default is "Trace"
|
||||||
LEVEL = Trace
|
LEVEL = Debug
|
||||||
|
|
||||||
; For "console" mode only
|
; For "console" mode only
|
||||||
[log.console]
|
[log.console]
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,8 @@ const (
|
||||||
CommentTypeChangeTitle
|
CommentTypeChangeTitle
|
||||||
// Delete Branch
|
// Delete Branch
|
||||||
CommentTypeDeleteBranch
|
CommentTypeDeleteBranch
|
||||||
|
// Dependency added
|
||||||
|
CommentTypeAddedDependency
|
||||||
)
|
)
|
||||||
|
|
||||||
// CommentTag defines comment tag type
|
// CommentTag defines comment tag type
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
"fmt"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// IssueDependency is connection request for receiving issue notification.
|
// IssueDependency is connection request for receiving issue notification.
|
||||||
|
|
@ -43,18 +42,20 @@ func (iw *IssueDependency) BeforeUpdate() {
|
||||||
iw.UpdatedUnix = u
|
iw.UpdatedUnix = u
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateOrUpdateIssueDependency sets or updates a dependency for an issue
|
// CreateOrUpdateIssueDependency creates a new dependency for an issue
|
||||||
func CreateOrUpdateIssueDependency(userID, issueID int64, depID int64) error {
|
func CreateOrUpdateIssueDependency(userID, issueID int64, depID int64) (err error, exists bool) {
|
||||||
err := x.Sync(new(IssueDependency))
|
err = x.Sync(new(IssueDependency))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err, exists
|
||||||
}
|
}
|
||||||
|
|
||||||
exists, err := issueDepExists(x, issueID, depID)
|
// Check if it aleready exists
|
||||||
|
exists, err = issueDepExists(x, issueID, depID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err, exists
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If it not exists, create it, otherwise show an error message
|
||||||
if !exists {
|
if !exists {
|
||||||
newId := new(IssueDependency)
|
newId := new(IssueDependency)
|
||||||
newId.UserID = userID
|
newId.UserID = userID
|
||||||
|
|
@ -62,20 +63,36 @@ func CreateOrUpdateIssueDependency(userID, issueID int64, depID int64) error {
|
||||||
newId.DependencyID = depID
|
newId.DependencyID = depID
|
||||||
|
|
||||||
if _, err := x.Insert(newId); err != nil {
|
if _, err := x.Insert(newId); err != nil {
|
||||||
return err
|
return err, exists
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add comment referencing to the stopwatch
|
||||||
|
comment := &Comment{
|
||||||
|
IssueID: issueID,
|
||||||
|
PosterID: userID,
|
||||||
|
Type: CommentTypeAddedDependency,
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := x.Insert(comment); err != nil {
|
||||||
|
return err, exists
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
fmt.Println("Dependency exists")
|
|
||||||
// TODO: Should display a message on issue page
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil, exists
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
// Check if the dependency already exists
|
||||||
func issueDepExists(e Engine, issueID int64, depID int64) (exists bool, err error) {
|
func issueDepExists(e Engine, issueID int64, depID int64) (exists bool, err error) {
|
||||||
var Dependencies = IssueDependency{IssueID: issueID, DependencyID: depID}
|
var Dependencies = IssueDependency{IssueID: issueID, DependencyID: depID}
|
||||||
|
|
||||||
//err = e.Where("issue_id = ?", issueID).Where("dependency_id = ?", depID).Find(&Dependencies)
|
|
||||||
exists, err = e.Get(&Dependencies)
|
exists, err = e.Get(&Dependencies)
|
||||||
|
|
||||||
|
// Check for dependencies the other way around
|
||||||
|
// Otherwise two issues could block each other which would result in none of them could be closed.
|
||||||
|
if !exists {
|
||||||
|
Dependencies.IssueID = depID
|
||||||
|
Dependencies.DependencyID = issueID
|
||||||
|
exists, err = e.Get(&Dependencies)
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -666,6 +666,40 @@ func (repo *Repository) CanEnableEditor() bool {
|
||||||
return !repo.IsMirror
|
return !repo.IsMirror
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (repo *Repository) BlockedByDependencies(issueID int64) (_ []*Issue, err error) {
|
||||||
|
|
||||||
|
issueDeps, err := repo.getBlockedByDependencies(x, issueID)
|
||||||
|
var issueDepsFull = make([]*Issue, 0)
|
||||||
|
|
||||||
|
for _, issueDep := range issueDeps{
|
||||||
|
issueDetails, _ := getIssueByID(x, issueDep.DependencyID)
|
||||||
|
issueDepsFull = append(issueDepsFull, issueDetails)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return issueDepsFull, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (repo *Repository) BlockingDependencies(issueID int64) (_ []*Issue, err error) {
|
||||||
|
|
||||||
|
issueDeps, err := repo.getBlockingDependencies(x, issueID)
|
||||||
|
var issueDepsFull = make([]*Issue, 0)
|
||||||
|
|
||||||
|
for _, issueDep := range issueDeps{
|
||||||
|
issueDetails, _ := getIssueByID(x, issueDep.IssueID)
|
||||||
|
issueDepsFull = append(issueDepsFull, issueDetails)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return issueDepsFull, nil
|
||||||
|
}
|
||||||
|
|
||||||
// NextIssueIndex returns the next issue index
|
// NextIssueIndex returns the next issue index
|
||||||
// FIXME: should have a mutex to prevent producing same index for two issues that are created
|
// FIXME: should have a mutex to prevent producing same index for two issues that are created
|
||||||
// closely enough.
|
// closely enough.
|
||||||
|
|
@ -2367,3 +2401,19 @@ func (repo *Repository) CreateNewBranch(doer *User, oldBranchName, branchName st
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get Blocked By Dependencies, aka all issues this issue is blocked by.
|
||||||
|
func (repo *Repository) getBlockedByDependencies(e Engine, issueID int64) (_ []IssueDependency, err error) {
|
||||||
|
var dependencies []IssueDependency
|
||||||
|
err = e.Where("issue_id = ?", issueID).Find(&dependencies) //
|
||||||
|
|
||||||
|
return dependencies, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get Blocking Dependencies, aka all issues this issue blocks.
|
||||||
|
func (repo *Repository) getBlockingDependencies(e Engine, issueID int64) (_ []IssueDependency, err error) {
|
||||||
|
var dependencies []IssueDependency
|
||||||
|
err = e.Where("dependency_id = ?", issueID).Find(&dependencies)
|
||||||
|
|
||||||
|
return dependencies, err
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -693,6 +693,13 @@ issues.attachment.open_tab = `Click to see "%s" in a new tab`
|
||||||
issues.attachment.download = `Click to download "%s"`
|
issues.attachment.download = `Click to download "%s"`
|
||||||
issues.subscribe = Subscribe
|
issues.subscribe = Subscribe
|
||||||
issues.unsubscribe = Unsubscribe
|
issues.unsubscribe = Unsubscribe
|
||||||
|
issues.dependency.title = Dependencies
|
||||||
|
issues.dependency.no_dependencies = This issue currently doesn't have any dependencies.
|
||||||
|
issues.dependency.add = Add
|
||||||
|
issues.dependency.cancel = Cancel
|
||||||
|
issues.dependency.add_header = Add New Dependency
|
||||||
|
issues.dependency.issue_number = Issuenumber
|
||||||
|
issues.dependency.added_dependency = `<a href="%[1]s">%[2]s</a> added a new dependency %[3]s`
|
||||||
|
|
||||||
pulls.desc = Pulls management your code review and merge requests
|
pulls.desc = Pulls management your code review and merge requests
|
||||||
pulls.new = New Pull Request
|
pulls.new = New Pull Request
|
||||||
|
|
|
||||||
|
|
@ -665,6 +665,10 @@ func ViewIssue(ctx *context.Context) {
|
||||||
ctx.Data["IsPullBranchDeletable"] = canDelete && pull.HeadRepo != nil && git.IsBranchExist(pull.HeadRepo.RepoPath(), pull.HeadBranch)
|
ctx.Data["IsPullBranchDeletable"] = canDelete && pull.HeadRepo != nil && git.IsBranchExist(pull.HeadRepo.RepoPath(), pull.HeadBranch)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get Dependencies
|
||||||
|
ctx.Data["BlockedByDependencies"], err = repo.BlockedByDependencies(issue.ID)
|
||||||
|
ctx.Data["BlockingDependencies"], err = repo.BlockingDependencies(issue.ID)
|
||||||
|
|
||||||
ctx.Data["Participants"] = participants
|
ctx.Data["Participants"] = participants
|
||||||
ctx.Data["NumParticipants"] = len(participants)
|
ctx.Data["NumParticipants"] = len(participants)
|
||||||
ctx.Data["Issue"] = issue
|
ctx.Data["Issue"] = issue
|
||||||
|
|
|
||||||
|
|
@ -28,12 +28,16 @@ func AddDependency(c *context.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := models.CreateOrUpdateIssueDependency(c.User.ID, issue.ID, dep); err != nil {
|
err, exists := models.CreateOrUpdateIssueDependency(c.User.ID, issue.ID, dep);
|
||||||
|
if err != nil {
|
||||||
c.Handle(http.StatusInternalServerError, "CreateOrUpdateIssueDependency", err)
|
c.Handle(http.StatusInternalServerError, "CreateOrUpdateIssueDependency", err)
|
||||||
fmt.Println("updateerr")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if exists {
|
||||||
|
c.Flash.Error("Dependency already exists!")
|
||||||
|
}
|
||||||
|
|
||||||
url := fmt.Sprintf("%s/issues/%d", c.Repo.RepoLink, issueIndex)
|
url := fmt.Sprintf("%s/issues/%d", c.Repo.RepoLink, issueIndex)
|
||||||
c.Redirect(url, http.StatusSeeOther)
|
c.Redirect(url, http.StatusSeeOther)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -140,5 +140,15 @@
|
||||||
<span class="text grey"><a href="{{.Poster.HomeLink}}">{{.Poster.Name}}</a>
|
<span class="text grey"><a href="{{.Poster.HomeLink}}">{{.Poster.Name}}</a>
|
||||||
{{$.i18n.Tr "repo.issues.delete_branch_at" .CommitSHA $createdStr | Safe}}
|
{{$.i18n.Tr "repo.issues.delete_branch_at" .CommitSHA $createdStr | Safe}}
|
||||||
</span>
|
</span>
|
||||||
|
{{else if eq .Type 12}}
|
||||||
|
<div class="event">
|
||||||
|
<span class="octicon octicon-primitive-dot"></span>
|
||||||
|
</div>
|
||||||
|
<a class="ui avatar image" href="{{.Poster.HomeLink}}">
|
||||||
|
<img src="{{.Poster.RelAvatarLink}}">
|
||||||
|
</a>
|
||||||
|
<span class="text grey">
|
||||||
|
{{$.i18n.Tr "repo.issues.dependency.added_dependency" .Poster.HomeLink .Poster.Name $createdStr | Safe}}
|
||||||
|
</span>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
||||||
|
|
@ -125,13 +125,53 @@
|
||||||
<div class="ui divider"></div>
|
<div class="ui divider"></div>
|
||||||
|
|
||||||
<div class="ui depending">
|
<div class="ui depending">
|
||||||
<span class="text"><strong>Dependencies</strong></span>
|
<span class="text"><strong>{{.i18n.Tr "repo.issues.dependency.title"}}</strong></span>
|
||||||
<div>
|
<br>
|
||||||
This issue currently doesn't have any dependencies.
|
<span class="text">This issue is blocked by:</span>
|
||||||
|
<div class="ui relaxed divided list">
|
||||||
|
{{range .BlockedByDependencies}}
|
||||||
|
<div class="item">
|
||||||
|
<div class="right floated content">
|
||||||
|
{{if .IsClosed}}
|
||||||
|
<div class="ui red mini label">
|
||||||
|
<i class="octicon octicon-issue-closed"></i>
|
||||||
|
</div>
|
||||||
|
{{else}}
|
||||||
|
<div class="ui green mini label">
|
||||||
|
<i class="octicon octicon-issue-opened"></i>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
<div class="ui black label">#{{.Index}}</div>
|
||||||
|
<a class="title has-emoji" href="{{$.RepoLink}}/issues/{{.Index}}">{{.Title}}</a>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ui relaxed divided list">
|
||||||
|
<span class="text">This issue blocks the following issues:</span>
|
||||||
|
{{range .BlockingDependencies}}
|
||||||
|
<div class="item">
|
||||||
|
<div class="right floated content">
|
||||||
|
{{if .IsClosed}}
|
||||||
|
<div class="ui red mini label">
|
||||||
|
<i class="octicon octicon-issue-closed"></i>
|
||||||
|
</div>
|
||||||
|
{{else}}
|
||||||
|
<div class="ui green mini label">
|
||||||
|
<i class="octicon octicon-issue-opened"></i>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
<div class="ui black label">#{{.Index}}</div>
|
||||||
|
<a class="title has-emoji" href="{{$.RepoLink}}/issues/{{.Index}}">{{.Title}}</a>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
<p>{{.i18n.Tr "repo.issues.dependency.no_dependencies"}}</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<button class="fluid green ui button" onclick="showAddDependencyModal();">
|
<button class="fluid green ui button" onclick="showAddDependencyModal();">
|
||||||
Add
|
{{.i18n.Tr "repo.issues.dependency.add"}}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -141,22 +181,22 @@
|
||||||
|
|
||||||
<div class="ui tiny modal">
|
<div class="ui tiny modal">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
Add new Dependency
|
{{.i18n.Tr "repo.issues.dependency.add_header"}}
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<form method="POST" action="{{$.RepoLink}}/issues/{{.Issue.Index}}/addDependency" id="addDependencyForm">
|
<form method="POST" action="{{$.RepoLink}}/issues/{{.Issue.Index}}/addDependency" id="addDependencyForm">
|
||||||
{{$.CsrfTokenHtml}}
|
{{$.CsrfTokenHtml}}
|
||||||
<div class="ui input">
|
<div class="ui input">
|
||||||
<input type="text" name="newDependency" id="newDependency" placeholder="Issuenumber...">
|
<input type="text" name="newDependency" id="newDependency" placeholder='{{.i18n.Tr "repo.issues.dependency.issue_number"}}'>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<div class="ui negative button">
|
<div class="ui negative button">
|
||||||
Cancel
|
{{.i18n.Tr "repo.issues.dependency.cancel"}}
|
||||||
</div>
|
</div>
|
||||||
<div class="ui positive right labeled icon button">
|
<div class="ui positive right labeled icon button">
|
||||||
Add
|
{{.i18n.Tr "repo.issues.dependency.add"}}
|
||||||
<i class="add icon"></i>
|
<i class="add icon"></i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user