Skip to content

Commit d38ae59

Browse files
noerw6543
andauthored
Add UI to delete tracked times (#14100)
Co-authored-by: 6543 <[email protected]>
1 parent 6a696b9 commit d38ae59

File tree

13 files changed

+123
-4
lines changed

13 files changed

+123
-4
lines changed

models/issue_comment.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,8 @@ type Comment struct {
136136
MilestoneID int64
137137
OldMilestone *Milestone `xorm:"-"`
138138
Milestone *Milestone `xorm:"-"`
139+
TimeID int64
140+
Time *TrackedTime `xorm:"-"`
139141
AssigneeID int64
140142
RemovedAssignee bool
141143
Assignee *User `xorm:"-"`
@@ -541,6 +543,16 @@ func (c *Comment) LoadDepIssueDetails() (err error) {
541543
return err
542544
}
543545

546+
// LoadTime loads the associated time for a CommentTypeAddTimeManual
547+
func (c *Comment) LoadTime() error {
548+
if c.Time != nil || c.TimeID == 0 {
549+
return nil
550+
}
551+
var err error
552+
c.Time, err = GetTrackedTimeByID(c.TimeID)
553+
return err
554+
}
555+
544556
func (c *Comment) loadReactions(e Engine, repo *Repository) (err error) {
545557
if c.Reactions != nil {
546558
return nil
@@ -692,6 +704,7 @@ func createComment(e *xorm.Session, opts *CreateCommentOptions) (_ *Comment, err
692704
MilestoneID: opts.MilestoneID,
693705
OldProjectID: opts.OldProjectID,
694706
ProjectID: opts.ProjectID,
707+
TimeID: opts.TimeID,
695708
RemovedAssignee: opts.RemovedAssignee,
696709
AssigneeID: opts.AssigneeID,
697710
AssigneeTeamID: opts.AssigneeTeamID,
@@ -859,6 +872,7 @@ type CreateCommentOptions struct {
859872
MilestoneID int64
860873
OldProjectID int64
861874
ProjectID int64
875+
TimeID int64
862876
AssigneeID int64
863877
AssigneeTeamID int64
864878
RemovedAssignee bool

models/issue_stopwatch.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ func CreateOrStopIssueStopwatch(user *User, issue *Issue) error {
100100
Repo: issue.Repo,
101101
Content: SecToTime(timediff),
102102
Type: CommentTypeStopTracking,
103+
TimeID: tt.ID,
103104
}); err != nil {
104105
return err
105106
}

models/issue_tracked_time.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ func AddTime(user *User, issue *Issue, amount int64, created time.Time) (*Tracke
162162
Doer: user,
163163
Content: SecToTime(amount),
164164
Type: CommentTypeAddTimeManual,
165+
TimeID: t.ID,
165166
}); err != nil {
166167
return nil, err
167168
}

models/migrations/migrations.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,8 @@ var migrations = []Migration{
292292
NewMigration("Add Sorting to ProjectBoard table", addSortingColToProjectBoard),
293293
// v172 -> v173
294294
NewMigration("Add sessions table for go-chi/session", addSessionTable),
295+
// v173 -> v174
296+
NewMigration("Add time_id column to Comment", addTimeIDCommentColumn),
295297
}
296298

297299
// GetCurrentDBVersion returns the current db version

models/migrations/v173.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright 2021 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package migrations
6+
7+
import (
8+
"fmt"
9+
10+
"xorm.io/xorm"
11+
)
12+
13+
func addTimeIDCommentColumn(x *xorm.Engine) error {
14+
type Comment struct {
15+
TimeID int64
16+
}
17+
18+
if err := x.Sync2(new(Comment)); err != nil {
19+
return fmt.Errorf("Sync2: %v", err)
20+
}
21+
return nil
22+
}

options/locale/locale_en-US.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1163,6 +1163,7 @@ issues.stop_tracking_history = `stopped working %s`
11631163
issues.cancel_tracking = Discard
11641164
issues.cancel_tracking_history = `cancelled time tracking %s`
11651165
issues.add_time = Manually Add Time
1166+
issues.del_time = Delete this time log
11661167
issues.add_time_short = Add Time
11671168
issues.add_time_cancel = Cancel
11681169
issues.add_time_history = `added spent time %s`

routers/repo/issue.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1416,6 +1416,10 @@ func ViewIssue(ctx *context.Context) {
14161416
ctx.ServerError("LoadPushCommits", err)
14171417
return
14181418
}
1419+
} else if comment.Type == models.CommentTypeAddTimeManual ||
1420+
comment.Type == models.CommentTypeStopTracking {
1421+
// drop error since times could be pruned from DB..
1422+
_ = comment.LoadTime()
14191423
}
14201424
}
14211425

routers/repo/issue_timetrack.go

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ import (
1010

1111
"code.gitea.io/gitea/models"
1212
"code.gitea.io/gitea/modules/context"
13-
auth "code.gitea.io/gitea/modules/forms"
13+
"code.gitea.io/gitea/modules/forms"
1414
"code.gitea.io/gitea/modules/web"
1515
)
1616

1717
// AddTimeManually tracks time manually
1818
func AddTimeManually(c *context.Context) {
19-
form := web.GetForm(c).(*auth.AddTimeManuallyForm)
19+
form := web.GetForm(c).(*forms.AddTimeManuallyForm)
2020
issue := GetActionIssue(c)
2121
if c.Written() {
2222
return
@@ -48,3 +48,39 @@ func AddTimeManually(c *context.Context) {
4848

4949
c.Redirect(url, http.StatusSeeOther)
5050
}
51+
52+
// DeleteTime deletes tracked time
53+
func DeleteTime(c *context.Context) {
54+
issue := GetActionIssue(c)
55+
if c.Written() {
56+
return
57+
}
58+
if !c.Repo.CanUseTimetracker(issue, c.User) {
59+
c.NotFound("CanUseTimetracker", nil)
60+
return
61+
}
62+
63+
t, err := models.GetTrackedTimeByID(c.ParamsInt64(":timeid"))
64+
if err != nil {
65+
if models.IsErrNotExist(err) {
66+
c.NotFound("time not found", err)
67+
return
68+
}
69+
c.Error(http.StatusInternalServerError, "GetTrackedTimeByID", err.Error())
70+
return
71+
}
72+
73+
// only OP or admin may delete
74+
if !c.IsSigned || (!c.IsUserSiteAdmin() && c.User.ID != t.UserID) {
75+
c.Error(http.StatusForbidden, "not allowed")
76+
return
77+
}
78+
79+
if err = models.DeleteTime(t); err != nil {
80+
c.ServerError("DeleteTime", err)
81+
return
82+
}
83+
84+
c.Flash.Success(c.Tr("repo.issues.del_time_history", models.SecToTime(t.Time)))
85+
c.Redirect(issue.HTMLURL())
86+
}

routers/routes/web.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,7 @@ func RegisterRoutes(m *web.Route) {
723723
m.Combo("/comments").Post(repo.MustAllowUserComment, bindIgnErr(auth.CreateCommentForm{}), repo.NewComment)
724724
m.Group("/times", func() {
725725
m.Post("/add", bindIgnErr(auth.AddTimeManuallyForm{}), repo.AddTimeManually)
726+
m.Post("/{timeid}/delete", repo.DeleteTime)
726727
m.Group("/stopwatch", func() {
727728
m.Post("/toggle", repo.IssueStopwatch)
728729
m.Post("/cancel", repo.CancelStopwatch)

templates/repo/issue/view_content/comments.tmpl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@
276276
<a class="author" href="{{.Poster.HomeLink}}">{{.Poster.GetDisplayName}}</a>
277277
{{$.i18n.Tr "repo.issues.stop_tracking_history" $createdStr | Safe}}
278278
</span>
279+
{{ template "repo/issue/view_content/comments_delete_time" Dict "ctx" $ "comment" . }}
279280
<div class="detail">
280281
{{svg "octicon-clock"}}
281282
<span class="text grey">{{.Content}}</span>
@@ -291,6 +292,7 @@
291292
<a class="author" href="{{.Poster.HomeLink}}">{{.Poster.GetDisplayName}}</a>
292293
{{$.i18n.Tr "repo.issues.add_time_history" $createdStr | Safe}}
293294
</span>
295+
{{ template "repo/issue/view_content/comments_delete_time" Dict "ctx" $ "comment" . }}
294296
<div class="detail">
295297
{{svg "octicon-clock"}}
296298
<span class="text grey">{{.Content}}</span>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{{ if .comment.Time }} {{/* compatibility with time comments made before v1.14 */}}
2+
{{ if (not .comment.Time.Deleted) }}
3+
{{ if (or .ctx.IsAdmin (and .ctx.IsSigned (eq .ctx.SignedUserID .comment.PosterID))) }}
4+
<span class="ui float right">
5+
<div class="ui mini modal issue-delete-time-modal" data-id="{{.comment.Time.ID}}">
6+
<form method="POST" class="delete-time-form" action="{{.ctx.RepoLink}}/issues/{{.ctx.Issue.Index}}/times/{{.comment.TimeID}}/delete">
7+
{{.ctx.CsrfTokenHtml}}
8+
</form>
9+
<div class="header">{{.ctx.i18n.Tr "repo.issues.del_time"}}</div>
10+
<div class="actions">
11+
<div class="ui red approve button">{{.ctx.i18n.Tr "repo.issues.context.delete"}}</div>
12+
<div class="ui cancel button">{{.ctx.i18n.Tr "repo.issues.add_time_cancel"}}</div>
13+
</div>
14+
</div>
15+
<button class="ui icon button compact mini issue-delete-time poping up" data-id="{{.comment.Time.ID}}" data-content="{{.ctx.i18n.Tr "repo.issues.del_time"}}" data-position="top right" data-variation="tiny inverted">
16+
{{svg "octicon-trashcan"}}
17+
</button>
18+
</span>
19+
{{end}}
20+
{{end}}
21+
{{end}}

templates/repo/issue/view_content/sidebar.tmpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@
348348
{{end}}
349349
<div class="ui buttons two fluid">
350350
<button class="ui button poping up issue-start-time" data-content='{{.i18n.Tr "repo.issues.start_tracking"}}' data-position="top center" data-variation="small inverted">{{.i18n.Tr "repo.issues.start_tracking_short"}}</button>
351-
<div class="ui mini modal">
351+
<div class="ui mini modal issue-start-time-modal">
352352
<div class="header">{{.i18n.Tr "repo.issues.add_time"}}</div>
353353
<div class="content">
354354
<form method="POST" id="add_time_manual_form" action="{{$.RepoLink}}/issues/{{.Issue.Index}}/times/add" class="ui action input fluid">

web_src/js/index.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3203,19 +3203,33 @@ function initVueApp() {
32033203

32043204
function initIssueTimetracking() {
32053205
$(document).on('click', '.issue-add-time', () => {
3206-
$('.mini.modal').modal({
3206+
$('.issue-start-time-modal').modal({
32073207
duration: 200,
32083208
onApprove() {
32093209
$('#add_time_manual_form').trigger('submit');
32103210
}
32113211
}).modal('show');
3212+
$('.issue-start-time-modal input').on('keydown', (e) => {
3213+
if ((e.keyCode || e.key) === 13) {
3214+
$('#add_time_manual_form').trigger('submit');
3215+
}
3216+
});
32123217
});
32133218
$(document).on('click', '.issue-start-time, .issue-stop-time', () => {
32143219
$('#toggle_stopwatch_form').trigger('submit');
32153220
});
32163221
$(document).on('click', '.issue-cancel-time', () => {
32173222
$('#cancel_stopwatch_form').trigger('submit');
32183223
});
3224+
$(document).on('click', 'button.issue-delete-time', function () {
3225+
const sel = `.issue-delete-time-modal[data-id="${$(this).data('id')}"]`;
3226+
$(sel).modal({
3227+
duration: 200,
3228+
onApprove() {
3229+
$(`${sel} form`).trigger('submit');
3230+
}
3231+
}).modal('show');
3232+
});
32193233
}
32203234

32213235
function initFilterBranchTagDropdown(selector) {

0 commit comments

Comments
 (0)