Replace status_id with in_progress boolean across mobile apps
- Remove TaskStatus model and status_id foreign key references - Add in_progress boolean field to task models and forms - Update TaskApi to use dedicated POST endpoints for task actions: - POST /tasks/:id/cancel/ instead of PATCH with is_cancelled - POST /tasks/:id/uncancel/ - POST /tasks/:id/archive/ - POST /tasks/:id/unarchive/ - Fix iOS TaskViewModel to use error-first pattern for Kotlin-Swift generic type bridging issues - Update iOS callback signatures to pass full TaskResponse instead of just taskId to avoid stale closure lookups - Add in_progress localization strings - Update widget preview data to use inProgress boolean 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -251,6 +251,7 @@ enum L10n {
|
||||
|
||||
// Task Card Actions
|
||||
static var inProgress: String { String(localized: "tasks_in_progress") }
|
||||
static var inProgressLabel: String { String(localized: "tasks_in_progress_label") }
|
||||
static var complete: String { String(localized: "tasks_complete") }
|
||||
static var edit: String { String(localized: "tasks_edit") }
|
||||
static var cancel: String { String(localized: "tasks_cancel") }
|
||||
|
||||
@@ -93,6 +93,10 @@ final class WidgetActionProcessor {
|
||||
let data = success.data {
|
||||
// Update widget with fresh data
|
||||
WidgetDataManager.shared.saveTasks(from: data)
|
||||
// Update summary from response (no extra API call needed)
|
||||
if let summary = data.summary {
|
||||
DataManager.shared.setTotalSummary(summary: summary)
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
print("WidgetActionProcessor: Error refreshing tasks: \(error)")
|
||||
|
||||
@@ -223,14 +223,15 @@ final class WidgetDataManager {
|
||||
let title: String
|
||||
let description: String?
|
||||
let priority: String?
|
||||
let status: String?
|
||||
let inProgress: Bool
|
||||
let dueDate: String?
|
||||
let category: String?
|
||||
let residenceName: String?
|
||||
let isOverdue: Bool
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case id, title, description, priority, status, category
|
||||
case id, title, description, priority, category
|
||||
case inProgress = "in_progress"
|
||||
case dueDate = "due_date"
|
||||
case residenceName = "residence_name"
|
||||
case isOverdue = "is_overdue"
|
||||
@@ -273,7 +274,7 @@ final class WidgetDataManager {
|
||||
title: task.title,
|
||||
description: task.description_,
|
||||
priority: task.priority?.name ?? "",
|
||||
status: task.status?.name,
|
||||
inProgress: task.inProgress,
|
||||
dueDate: task.dueDate,
|
||||
category: task.category?.name ?? "",
|
||||
residenceName: "", // No longer available in API, residence lookup needed
|
||||
@@ -325,14 +326,9 @@ final class WidgetDataManager {
|
||||
func getUpcomingTasks() -> [WidgetTask] {
|
||||
let allTasks = loadTasks()
|
||||
|
||||
// Filter for pending/in-progress tasks (non-archived, non-completed)
|
||||
let upcoming = allTasks.filter { task in
|
||||
let status = task.status?.lowercased() ?? ""
|
||||
return status == "pending" || status == "in_progress" || status == "in progress"
|
||||
}
|
||||
|
||||
// All loaded tasks are already filtered (archived and completed columns are excluded during save)
|
||||
// Sort by due date (earliest first), with overdue at top
|
||||
return upcoming.sorted { task1, task2 in
|
||||
return allTasks.sorted { task1, task2 in
|
||||
// Overdue tasks first
|
||||
if task1.isOverdue != task2.isOverdue {
|
||||
return task1.isOverdue
|
||||
|
||||
Reference in New Issue
Block a user