From 2215aaa458b318edb16337ab56cf658117023eb4 Mon Sep 17 00:00:00 2001 From: Peter Stone Date: Mon, 19 Jan 2026 09:11:04 -1000 Subject: Implement Unified Quick Add for Tasks tab (Phase 3 Step 8) Add Quick Add form to create Todoist tasks or Trello cards directly from the Tasks tab with optional due date support. Features: - HandleUnifiedAdd handler with due date parsing - HandleGetListsOptions for dynamic Trello list loading - Quick Add form with source toggle (Todoist/Trello) - Date picker for due dates - HX-Trigger refresh after successful creation - Pass boards to tasks-tab template for board selector Cleanup: - Remove resolved issue tracking files Co-Authored-By: Claude Opus 4.5 --- issues/bug_001_template_rendering.md | 17 -------- issues/bug_002_tab_state.md | 31 -------------- issues/phase3_step1_trello_write.md | 78 ------------------------------------ issues/phase3_step2_trello_lists.md | 21 ---------- issues/phase3_step3_trello_ui.md | 36 ----------------- issues/phase3_step4_todoist_write.md | 40 ------------------ 6 files changed, 223 deletions(-) delete mode 100644 issues/bug_001_template_rendering.md delete mode 100644 issues/bug_002_tab_state.md delete mode 100644 issues/phase3_step1_trello_write.md delete mode 100644 issues/phase3_step2_trello_lists.md delete mode 100644 issues/phase3_step3_trello_ui.md delete mode 100644 issues/phase3_step4_todoist_write.md (limited to 'issues') diff --git a/issues/bug_001_template_rendering.md b/issues/bug_001_template_rendering.md deleted file mode 100644 index 61a8022..0000000 --- a/issues/bug_001_template_rendering.md +++ /dev/null @@ -1,17 +0,0 @@ -# Bug 001: Template Error in Notes Tab - -**Status:** Resolved -**Severity:** High (Runtime Panic/Error) -**Component:** Frontend/Handlers - -## Description -The `notes-tab` template attempts to render the `error-banner` partial, which expects an `.Errors` field in the data context. However, the `HandleNotes` handler was passing an anonymous struct containing only `Notes`, causing a template execution error. - -## Root Cause -Mismatch between template expectation (`{{.Errors}}`) and handler data structure (`struct { Notes []models.Note }`). - -## Fix -Updated `HandleNotes` in `internal/handlers/tabs.go` to include `Errors []string` in the data struct passed to the template. - -## Verification -A reproduction test case `internal/handlers/template_test.go` was created to verify that the `notes-tab` template can be successfully executed with the updated data structure. diff --git a/issues/bug_002_tab_state.md b/issues/bug_002_tab_state.md deleted file mode 100644 index c8c7c09..0000000 --- a/issues/bug_002_tab_state.md +++ /dev/null @@ -1,31 +0,0 @@ -# Bug 002: Tab State Persistence (RESOLVED) - -## Status -**RESOLVED** - -## Description -When a user switches tabs (e.g., to "Notes") and refreshes the page, the dashboard resets to the default "Tasks" tab. This is a poor user experience. The application should respect the `?tab=` query parameter and update the URL when tabs are switched. - -## Root Cause -1. **Server-Side:** `HandleDashboard` does not read the `tab` query parameter or pass it to the template. -2. **Client-Side:** `index.html` hardcodes the initial active tab to "Tasks". -3. **Client-Side:** Tab buttons use `hx-push-url="false"`, so the URL doesn't update on click. - -## Resolution -1. **Model Update:** Added `ActiveTab` field to `DashboardData` struct in `internal/models/types.go`. -2. **Handler Update:** Updated `HandleDashboard` in `internal/handlers/handlers.go` to: - * Read `r.URL.Query().Get("tab")`. - * Validate the tab name (defaulting to "tasks"). - * Set `ActiveTab` in the data passed to the template. -3. **Template Update:** Updated `web/templates/index.html` to: - * Use `{{if eq .ActiveTab "..."}}` to conditionally apply the `tab-button-active` class. - * Set the initial `hx-get` for `#tab-content` to `/tabs/{{.ActiveTab}}`. - * Set `hx-push-url="?tab=..."` on all tab buttons to ensure the URL updates in the browser history. -4. **Client-Side Update:** Updated `web/static/js/app.js` to initialize `currentTab` from the URL query parameter. - -## Verification -* **Automated Test:** Created `internal/handlers/tab_state_test.go` which verifies: - * Default load (`/`) renders "tasks" as active. - * Query param load (`/?tab=notes`) renders "notes" as active. - * All valid tab names are supported. -* **Manual Verification:** Confirmed that clicking tabs updates the URL and refreshing the page preserves the active tab. diff --git a/issues/phase3_step1_trello_write.md b/issues/phase3_step1_trello_write.md deleted file mode 100644 index 8f13e47..0000000 --- a/issues/phase3_step1_trello_write.md +++ /dev/null @@ -1,78 +0,0 @@ -# Phase 3 Step 1: Trello Write Operations - -**Status:** Active -**Priority:** High -**Feature:** Interactive Dashboard (Write Ops) - -## Description -Currently, the Trello client is read-only. We need to implement `CreateCard` and `UpdateCard` to enable interactivity (adding tasks, moving cards, completing items). - -## Requirements -1. **CreateCard:** - * Method: `POST /1/cards` - * Parameters: `name`, `idList`, `desc` (optional), `due` (optional). - * Returns: Created `models.Card`. - -2. **UpdateCard:** - * Method: `PUT /1/cards/{id}` - * Parameters: Flexible map of updates (e.g., `idList` to move, `closed=true` to archive). - * Returns: Updated `models.Card` (or just error). - -## Reproduction / Test Plan -Since we cannot hit the real Trello API in tests, we will use `httptest.Server` to mock the API responses. - -### `internal/api/trello_test.go` -```go -package api - -import ( - "encoding/json" - "net/http" - "net/http/httptest" - "testing" - "time" - - "task-dashboard/internal/models" -) - -func TestTrelloClient_CreateCard(t *testing.T) { - // Mock Server - server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.Method != "POST" { - t.Errorf("Expected POST, got %s", r.Method) - } - if r.URL.Path != "/1/cards" { - t.Errorf("Expected /1/cards, got %s", r.URL.Path) - } - - // Verify params - r.ParseForm() - if r.Form.Get("name") != "New Task" { - t.Errorf("Expected name='New Task', got %s", r.Form.Get("name")) - } - - // Return mock response - card := models.Card{ - ID: "new-card-id", - Name: "New Task", - } - json.NewEncoder(w).Encode(card) - })) - defer server.Close() - - client := &TrelloClient{ - BaseURL: server.URL, - Key: "test-key", - Token: "test-token", - Client: server.Client(), - } - - card, err := client.CreateCard("list-id", "New Task", "Description", nil) - if err != nil { - t.Fatalf("CreateCard failed: %v", err) - } - if card.ID != "new-card-id" { - t.Errorf("Expected ID 'new-card-id', got %s", card.ID) - } -} -``` diff --git a/issues/phase3_step2_trello_lists.md b/issues/phase3_step2_trello_lists.md deleted file mode 100644 index f16e226..0000000 --- a/issues/phase3_step2_trello_lists.md +++ /dev/null @@ -1,21 +0,0 @@ -# Phase 3 Step 2: Trello Lists Support - -## Description -To enable "Add Card" functionality, we need to know the available lists for each board. Currently, the `Board` model does not include lists, and the API client only fetches lists internally to map names. - -## Requirements -1. **Update Models**: Add `List` struct and `Lists` field to `Board`. -2. **Update Interface**: Add `GetLists` to `TrelloAPI`. -3. **Update Client**: - * Refactor `getLists` to return `[]models.List`. - * Update `GetBoardsWithCards` to populate `board.Lists`. - * Implement public `GetLists`. - -## Plan -1. Modify `internal/models/types.go`. -2. Modify `internal/api/interfaces.go`. -3. Modify `internal/api/trello.go`. - -## Verification -* Run `go test ./internal/api/...` to ensure no regressions. -* (Implicit) The UI will eventually use this data. diff --git a/issues/phase3_step3_trello_ui.md b/issues/phase3_step3_trello_ui.md deleted file mode 100644 index 92dd8a5..0000000 --- a/issues/phase3_step3_trello_ui.md +++ /dev/null @@ -1,36 +0,0 @@ -# Phase 3 Step 3: Trello UI & Handlers - -**Status:** Open -**Priority:** High -**Created:** 2024-05-22 - -## Description -Implement the UI and backend handlers to enable creating and completing Trello cards directly from the dashboard. - -## Requirements - -### 1. UI Updates -* **Refactor:** Extract individual board rendering into a new partial `web/templates/partials/trello-board.html`. -* **Add Card:** Add a "Quick Add" form to each board (using `
` for simplicity) that allows selecting a List and entering a Name. -* **Complete Card:** Add a checkbox to each card that marks it as complete (archives/closes it). - -### 2. Backend Handlers -* `HandleCreateCard`: - * POST `/cards` - * Params: `board_id`, `list_id`, `name` - * Action: Call `CreateCard` API. - * Response: Re-render the specific board partial with updated data. -* `HandleCompleteCard`: - * POST `/cards/complete` - * Params: `card_id` - * Action: Call `UpdateCard` API (set `closed=true`). - * Response: Empty string (removes the card from UI via HTMX). - -### 3. Routing -* Register the new routes in `cmd/dashboard/main.go`. - -## Implementation Plan -1. Create `web/templates/partials/trello-board.html`. -2. Update `web/templates/partials/trello-boards.html`. -3. Implement handlers in `internal/handlers/handlers.go`. -4. Register routes in `cmd/dashboard/main.go`. diff --git a/issues/phase3_step4_todoist_write.md b/issues/phase3_step4_todoist_write.md deleted file mode 100644 index f68a963..0000000 --- a/issues/phase3_step4_todoist_write.md +++ /dev/null @@ -1,40 +0,0 @@ -# Phase 3 Step 4: Todoist Write Operations - -## Goal -Implement write operations for Todoist (Create Task, Complete Task) and update the UI to support them. - -## Requirements - -### Backend -1. **Models**: - * Add `Project` struct to `internal/models/types.go`. - * Add `Projects []Project` to `DashboardData`. -2. **API (`internal/api/todoist.go`)**: - * Refactor `GetProjects` to return `[]models.Project`. - * Implement `CreateTask(content, projectID string)`. - * Implement `CompleteTask(taskID string)`. - * Refactor `baseURL` to be a struct field for testability. -3. **Handlers (`internal/handlers/handlers.go`)**: - * Update `aggregateData` to fetch projects and populate `DashboardData`. - * Implement `HandleCreateTask`: - * Parse form (`content`, `project_id`). - * Call `CreateTask`. - * Return updated task list partial. - * Implement `HandleCompleteTask`: - * Call `CompleteTask`. - * Return empty string (to remove from DOM). - -### Frontend -1. **Template (`web/templates/partials/todoist-tasks.html`)**: - * Add "Quick Add" form at the top. - * Input: Task content. - * Select: Project (populated from `.Projects`). - * Update Task Items: - * Add Checkbox. - * `hx-post="/tasks/complete"`. - * `hx-target="closest .todoist-task-item"`. - * `hx-swap="outerHTML"`. - -## Verification -* Unit tests for API client. -* Manual verification of UI flows. -- cgit v1.2.3