1
1
mirror of https://github.com/go-gitea/gitea synced 2025-07-23 02:38:35 +00:00

Issue time estimate, meaningful time tracking (#23113)

Redesign the time tracker side bar, and add "time estimate" support (in "1d 2m" format)

Closes #23112

---------

Co-authored-by: stuzer05 <stuzer05@gmail.com>
Co-authored-by: Yarden Shoham <hrsi88@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: 6543 <6543@obermui.de>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
Illya Marchenko
2024-12-05 15:07:53 +02:00
committed by GitHub
parent c5422fae9a
commit 936665bf85
21 changed files with 390 additions and 164 deletions

View File

@@ -4,7 +4,6 @@
package repo
import (
"net/http"
"strings"
"code.gitea.io/gitea/models/db"
@@ -40,8 +39,7 @@ func IssueStopwatch(c *context.Context) {
c.Flash.Success(c.Tr("repo.issues.tracker_auto_close"))
}
url := issue.Link()
c.Redirect(url, http.StatusSeeOther)
c.JSONRedirect("")
}
// CancelStopwatch cancel the stopwatch
@@ -72,8 +70,7 @@ func CancelStopwatch(c *context.Context) {
})
}
url := issue.Link()
c.Redirect(url, http.StatusSeeOther)
c.JSONRedirect("")
}
// GetActiveStopwatch is the middleware that sets .ActiveStopwatch on context

View File

@@ -5,6 +5,7 @@ package repo
import (
"net/http"
"strings"
"time"
"code.gitea.io/gitea/models/db"
@@ -13,6 +14,7 @@ import (
"code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/services/context"
"code.gitea.io/gitea/services/forms"
issue_service "code.gitea.io/gitea/services/issue"
)
// AddTimeManually tracks time manually
@@ -26,19 +28,16 @@ func AddTimeManually(c *context.Context) {
c.NotFound("CanUseTimetracker", nil)
return
}
url := issue.Link()
if c.HasError() {
c.Flash.Error(c.GetErrMsg())
c.Redirect(url)
c.JSONError(c.GetErrMsg())
return
}
total := time.Duration(form.Hours)*time.Hour + time.Duration(form.Minutes)*time.Minute
if total <= 0 {
c.Flash.Error(c.Tr("repo.issues.add_time_sum_to_small"))
c.Redirect(url, http.StatusSeeOther)
c.JSONError(c.Tr("repo.issues.add_time_sum_to_small"))
return
}
@@ -47,7 +46,7 @@ func AddTimeManually(c *context.Context) {
return
}
c.Redirect(url, http.StatusSeeOther)
c.JSONRedirect("")
}
// DeleteTime deletes tracked time
@@ -83,5 +82,38 @@ func DeleteTime(c *context.Context) {
}
c.Flash.Success(c.Tr("repo.issues.del_time_history", util.SecToTime(t.Time)))
c.Redirect(issue.Link())
c.JSONRedirect("")
}
func UpdateIssueTimeEstimate(ctx *context.Context) {
issue := GetActionIssue(ctx)
if ctx.Written() {
return
}
if !ctx.IsSigned || (!issue.IsPoster(ctx.Doer.ID) && !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull)) {
ctx.Error(http.StatusForbidden)
return
}
timeStr := strings.TrimSpace(ctx.FormString("time_estimate"))
total, err := util.TimeEstimateParse(timeStr)
if err != nil {
ctx.JSONError(ctx.Tr("repo.issues.time_estimate_invalid"))
return
}
// No time changed
if issue.TimeEstimate == total {
ctx.JSONRedirect("")
return
}
if err := issue_service.ChangeTimeEstimate(ctx, issue, ctx.Doer, total); err != nil {
ctx.ServerError("ChangeTimeEstimate", err)
return
}
ctx.JSONRedirect("")
}

View File

@@ -1235,6 +1235,7 @@ func registerRoutes(m *web.Router) {
m.Post("/cancel", repo.CancelStopwatch)
})
})
m.Post("/time_estimate", repo.UpdateIssueTimeEstimate)
m.Post("/reactions/{action}", web.Bind(forms.ReactionForm{}), repo.ChangeIssueReaction)
m.Post("/lock", reqRepoIssuesOrPullsWriter, web.Bind(forms.IssueLockForm{}), repo.LockIssue)
m.Post("/unlock", reqRepoIssuesOrPullsWriter, repo.UnlockIssue)