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:
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user