Centralize kanban state in TaskViewModel to eliminate duplicate code

Move tasksResponse state and updateTaskInKanban logic from individual views
into TaskViewModel. Both AllTasksView and ResidenceDetailView now delegate
to the shared ViewModel, reducing code duplication and ensuring consistent
task state management across the app.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Trey t
2025-12-02 22:07:52 -06:00
parent 00e303c3be
commit b79fda8aee
3 changed files with 168 additions and 169 deletions

View File

@@ -5,9 +5,6 @@ struct AllTasksView: View {
@StateObject private var taskViewModel = TaskViewModel()
@StateObject private var residenceViewModel = ResidenceViewModel()
@StateObject private var subscriptionCache = SubscriptionCacheWrapper.shared
@State private var tasksResponse: TaskColumnsResponse?
@State private var isLoadingTasks = false
@State private var tasksError: String?
@State private var showAddTask = false
@State private var showEditTask = false
@State private var showingUpgradePrompt = false
@@ -20,20 +17,13 @@ struct AllTasksView: View {
@State private var selectedTaskForCancel: TaskResponse?
@State private var showCancelConfirmation = false
// Count total tasks across all columns
private var totalTaskCount: Int {
guard let response = tasksResponse else { return 0 }
return response.columns.reduce(0) { $0 + $1.tasks.count }
}
private var hasNoTasks: Bool {
guard let response = tasksResponse else { return true }
return response.columns.allSatisfy { $0.tasks.isEmpty }
}
private var hasTasks: Bool {
!hasNoTasks
}
// Use ViewModel's computed properties
private var totalTaskCount: Int { taskViewModel.totalTaskCount }
private var hasNoTasks: Bool { taskViewModel.hasNoTasks }
private var hasTasks: Bool { taskViewModel.hasTasks }
private var tasksResponse: TaskColumnsResponse? { taskViewModel.tasksResponse }
private var isLoadingTasks: Bool { taskViewModel.isLoadingTasks }
private var tasksError: String? { taskViewModel.tasksError }
var body: some View {
mainContent
@@ -273,76 +263,12 @@ struct AllTasksView: View {
}
}
private func updateTaskInKanban(_ updatedTask: TaskResponse) {
guard let currentResponse = tasksResponse else { return }
let targetColumn = updatedTask.kanbanColumn ?? "completed_tasks"
var newColumns: [TaskColumn] = []
for column in currentResponse.columns {
// Remove task from this column if it exists
var filteredTasks = column.tasks.filter { $0.id != updatedTask.id }
// Add task to target column
if column.name == targetColumn {
filteredTasks.append(updatedTask)
}
// Create new column with updated tasks and count
let newColumn = TaskColumn(
name: column.name,
displayName: column.displayName,
buttonTypes: column.buttonTypes,
icons: column.icons,
color: column.color,
tasks: filteredTasks,
count: Int32(filteredTasks.count)
)
newColumns.append(newColumn)
}
// Update the response
tasksResponse = TaskColumnsResponse(
columns: newColumns,
daysThreshold: currentResponse.daysThreshold,
residenceId: currentResponse.residenceId
)
private func loadAllTasks(forceRefresh: Bool = false) {
taskViewModel.loadTasks(forceRefresh: forceRefresh)
}
private func loadAllTasks(forceRefresh: Bool = false) {
guard TokenStorage.shared.getToken() != nil else { return }
isLoadingTasks = true
tasksError = nil
Task {
do {
let result = try await APILayer.shared.getTasks(forceRefresh: forceRefresh)
await MainActor.run {
if let success = result as? ApiResultSuccess<TaskColumnsResponse>,
let data = success.data {
self.tasksResponse = data
self.isLoadingTasks = false
self.tasksError = nil
// Update widget data
WidgetDataManager.shared.saveTasks(from: data)
} else if let error = result as? ApiResultError {
self.tasksError = error.message
self.isLoadingTasks = false
} else {
self.tasksError = "Failed to load tasks"
self.isLoadingTasks = false
}
}
} catch {
await MainActor.run {
self.tasksError = error.localizedDescription
self.isLoadingTasks = false
}
}
}
private func updateTaskInKanban(_ updatedTask: TaskResponse) {
taskViewModel.updateTaskInKanban(updatedTask)
}
}