Allow deleting projects from the project picker with x/X.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -153,6 +153,28 @@ func (s *JSONTimeStore) Delete(id string) error {
|
||||
return s.writeUnlocked(out)
|
||||
}
|
||||
|
||||
// DeleteByProject removes all time entries for a project.
|
||||
func (s *JSONTimeStore) DeleteByProject(projectID string) error {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
if projectID == "" {
|
||||
return fmt.Errorf("projectId is required")
|
||||
}
|
||||
entries, err := s.readUnlocked()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
out := make([]TimeEntry, 0, len(entries))
|
||||
for _, e := range entries {
|
||||
if e.ProjectID == projectID {
|
||||
continue
|
||||
}
|
||||
out = append(out, e)
|
||||
}
|
||||
return s.writeUnlocked(out)
|
||||
}
|
||||
|
||||
// SumByTicket returns total duration for a ticket.
|
||||
func (s *JSONTimeStore) SumByTicket(ticketID string) (time.Duration, error) {
|
||||
entries, err := s.ListByTicket(ticketID)
|
||||
|
||||
@@ -69,3 +69,25 @@ func TestJSONTimeStoreRoundTrip(t *testing.T) {
|
||||
t.Fatalf("after delete: %v len=%d path=%s", err, len(list), filepath.Join(dir, "time_entries.json"))
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONTimeStoreDeleteByProject(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
store := ticket.NewJSONTimeStore(dir)
|
||||
|
||||
for _, e := range []ticket.TimeEntry{
|
||||
{TicketID: "a", ProjectID: "p1", Duration: time.Hour, Source: ticket.SourceManual},
|
||||
{TicketID: "b", ProjectID: "p1", Duration: time.Minute, Source: ticket.SourceManual},
|
||||
{TicketID: "c", ProjectID: "p2", Duration: 30 * time.Minute, Source: ticket.SourceManual},
|
||||
} {
|
||||
if _, err := store.Create(e); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
if err := store.DeleteByProject("p1"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
list, err := store.List()
|
||||
if err != nil || len(list) != 1 || list[0].ProjectID != "p2" {
|
||||
t.Fatalf("after DeleteByProject: %v %+v", err, list)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ type TimeStore interface {
|
||||
Create(e TimeEntry) (TimeEntry, error)
|
||||
Update(e TimeEntry) error
|
||||
Delete(id string) error
|
||||
DeleteByProject(projectID string) error
|
||||
SumByTicket(ticketID string) (time.Duration, error)
|
||||
|
||||
LoadActiveTimer() (*ActiveTimer, error)
|
||||
|
||||
Reference in New Issue
Block a user