diff options
Diffstat (limited to 'internal/handlers')
| -rw-r--r-- | internal/handlers/handlers.go | 20 | ||||
| -rw-r--r-- | internal/handlers/tab_state_test.go | 2 | ||||
| -rw-r--r-- | internal/handlers/timeline.go | 2 | ||||
| -rw-r--r-- | internal/handlers/timeline_logic.go | 29 | ||||
| -rw-r--r-- | internal/handlers/timeline_logic_test.go | 2 |
5 files changed, 50 insertions, 5 deletions
diff --git a/internal/handlers/handlers.go b/internal/handlers/handlers.go index 115d903..0424e40 100644 --- a/internal/handlers/handlers.go +++ b/internal/handlers/handlers.go @@ -29,12 +29,13 @@ type Handler struct { trelloClient api.TrelloAPI planToEatClient api.PlanToEatAPI googleCalendarClient api.GoogleCalendarAPI + googleTasksClient api.GoogleTasksAPI config *config.Config templates *template.Template } // New creates a new Handler instance -func New(s *store.Store, todoist api.TodoistAPI, trello api.TrelloAPI, planToEat api.PlanToEatAPI, googleCalendar api.GoogleCalendarAPI, cfg *config.Config) *Handler { +func New(s *store.Store, todoist api.TodoistAPI, trello api.TrelloAPI, planToEat api.PlanToEatAPI, googleCalendar api.GoogleCalendarAPI, googleTasks api.GoogleTasksAPI, cfg *config.Config) *Handler { // Parse templates including partials tmpl, err := template.ParseGlob(filepath.Join(cfg.TemplateDir, "*.html")) if err != nil { @@ -53,6 +54,7 @@ func New(s *store.Store, todoist api.TodoistAPI, trello api.TrelloAPI, planToEat trelloClient: trello, planToEatClient: planToEat, googleCalendarClient: googleCalendar, + googleTasksClient: googleTasks, config: cfg, templates: tmpl, } @@ -640,6 +642,22 @@ func (h *Handler) handleAtomToggle(w http.ResponseWriter, r *http.Request, compl } else { err = h.store.UnresolveBug(bugID) } + case "gtasks": + // Google Tasks - need list ID from form or use default + listID := r.FormValue("listId") + if listID == "" { + listID = "@default" + } + if h.googleTasksClient != nil { + if complete { + err = h.googleTasksClient.CompleteTask(ctx, listID, id) + } else { + err = h.googleTasksClient.UncompleteTask(ctx, listID, id) + } + } else { + JSONError(w, http.StatusServiceUnavailable, "Google Tasks not configured", nil) + return + } default: JSONError(w, http.StatusBadRequest, "Unknown source: "+source, nil) return diff --git a/internal/handlers/tab_state_test.go b/internal/handlers/tab_state_test.go index 71c6ed8..b95843e 100644 --- a/internal/handlers/tab_state_test.go +++ b/internal/handlers/tab_state_test.go @@ -30,7 +30,7 @@ func TestHandleDashboard_TabState(t *testing.T) { } // Create handler - h := New(db, todoistClient, trelloClient, nil, nil, cfg) + h := New(db, todoistClient, trelloClient, nil, nil, nil, cfg) // Skip if templates are not loaded (test environment issue) if h.templates == nil { diff --git a/internal/handlers/timeline.go b/internal/handlers/timeline.go index 37e688f..5e583d6 100644 --- a/internal/handlers/timeline.go +++ b/internal/handlers/timeline.go @@ -51,7 +51,7 @@ func (h *Handler) HandleTimeline(w http.ResponseWriter, r *http.Request) { end := start.AddDate(0, 0, days) // Call BuildTimeline - items, err := BuildTimeline(r.Context(), h.store, h.googleCalendarClient, start, end) + items, err := BuildTimeline(r.Context(), h.store, h.googleCalendarClient, h.googleTasksClient, start, end) if err != nil { JSONError(w, http.StatusInternalServerError, "Failed to build timeline", err) return diff --git a/internal/handlers/timeline_logic.go b/internal/handlers/timeline_logic.go index 553593d..5ea44b5 100644 --- a/internal/handlers/timeline_logic.go +++ b/internal/handlers/timeline_logic.go @@ -13,7 +13,7 @@ import ( ) // BuildTimeline aggregates and normalizes data into a timeline structure -func BuildTimeline(ctx context.Context, s *store.Store, calendarClient api.GoogleCalendarAPI, start, end time.Time) ([]models.TimelineItem, error) { +func BuildTimeline(ctx context.Context, s *store.Store, calendarClient api.GoogleCalendarAPI, tasksClient api.GoogleTasksAPI, start, end time.Time) ([]models.TimelineItem, error) { var items []models.TimelineItem now := config.Now() @@ -151,6 +151,33 @@ func BuildTimeline(ctx context.Context, s *store.Store, calendarClient api.Googl } } + // 5. Fetch Google Tasks + if tasksClient != nil { + gTasks, err := tasksClient.GetTasksByDateRange(ctx, start, end) + if err == nil { + for _, gTask := range gTasks { + taskTime := start // Default to start of range if no due date + if gTask.DueDate != nil { + taskTime = *gTask.DueDate + } + item := models.TimelineItem{ + ID: gTask.ID, + Type: models.TimelineItemTypeGTask, + Title: gTask.Title, + Time: taskTime, + Description: gTask.Notes, + URL: gTask.URL, + OriginalItem: gTask, + IsCompleted: gTask.Completed, + Source: "gtasks", + ListID: gTask.ListID, + } + item.ComputeDaySection(now) + items = append(items, item) + } + } + } + // Sort items by Time sort.Slice(items, func(i, j int) bool { return items[i].Time.Before(items[j].Time) diff --git a/internal/handlers/timeline_logic_test.go b/internal/handlers/timeline_logic_test.go index 038f836..5d0a425 100644 --- a/internal/handlers/timeline_logic_test.go +++ b/internal/handlers/timeline_logic_test.go @@ -130,7 +130,7 @@ func TestBuildTimeline(t *testing.T) { start := time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC) end := time.Date(2023, 1, 2, 0, 0, 0, 0, time.UTC) - items, err := BuildTimeline(context.Background(), s, mockCal, start, end) + items, err := BuildTimeline(context.Background(), s, mockCal, nil, start, end) if err != nil { t.Fatalf("BuildTimeline failed: %v", err) } |
