Add cancel task confirmation dialog

- Add L10n strings for cancel confirmation
- Add confirmation dialog to ResidenceDetailView
- Fix AllTasksView cancel dialog (was using archive strings)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-01-25 10:46:13 -06:00
parent 49f4cf168f
commit 09be5fa444
4 changed files with 47 additions and 9 deletions

View File

@@ -216,6 +216,8 @@ enum L10n {
static var deleteTask: String { String(localized: "tasks_delete_task") } static var deleteTask: String { String(localized: "tasks_delete_task") }
static var archiveConfirm: String { String(localized: "tasks_archive_confirm") } static var archiveConfirm: String { String(localized: "tasks_archive_confirm") }
static var archive: String { String(localized: "tasks_archive") } static var archive: String { String(localized: "tasks_archive") }
static var cancelTask: String { String(localized: "tasks_cancel_task") }
static var cancelConfirm: String { String(localized: "tasks_cancel_confirm") }
static var noTasks: String { String(localized: "tasks_no_tasks") } static var noTasks: String { String(localized: "tasks_no_tasks") }
// Complete Task View // Complete Task View

View File

@@ -25673,6 +25673,28 @@
} }
} }
}, },
"tasks_cancel_confirm" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Are you sure you want to cancel this task?"
}
}
}
},
"tasks_cancel_task" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cancel Task"
}
}
}
},
"tasks_category" : { "tasks_category" : {
"extractionState" : "manual", "extractionState" : "manual",
"localizations" : { "localizations" : {

View File

@@ -25,6 +25,8 @@ struct ResidenceDetailView: View {
@State private var selectedTaskForComplete: TaskResponse? @State private var selectedTaskForComplete: TaskResponse?
@State private var selectedTaskForArchive: TaskResponse? @State private var selectedTaskForArchive: TaskResponse?
@State private var showArchiveConfirmation = false @State private var showArchiveConfirmation = false
@State private var selectedTaskForCancel: TaskResponse?
@State private var showCancelConfirmation = false
@State private var hasAppeared = false @State private var hasAppeared = false
@State private var showReportAlert = false @State private var showReportAlert = false
@@ -144,6 +146,21 @@ struct ResidenceDetailView: View {
Text("Are you sure you want to archive \"\(task.title)\"? You can unarchive it later from archived tasks.") Text("Are you sure you want to archive \"\(task.title)\"? You can unarchive it later from archived tasks.")
} }
} }
.alert(L10n.Tasks.cancelTask, isPresented: $showCancelConfirmation) {
Button(L10n.Common.no, role: .cancel) {
selectedTaskForCancel = nil
}
Button(L10n.Common.yes, role: .destructive) {
if let task = selectedTaskForCancel {
taskViewModel.cancelTask(id: task.id) { _ in
loadResidenceTasks()
}
selectedTaskForCancel = nil
}
}
} message: {
Text(L10n.Tasks.cancelConfirm)
}
.sheet(isPresented: $showingUpgradePrompt) { .sheet(isPresented: $showingUpgradePrompt) {
UpgradePromptView(triggerKey: upgradeTriggerKey.isEmpty ? "add_11th_task" : upgradeTriggerKey, isPresented: $showingUpgradePrompt) UpgradePromptView(triggerKey: upgradeTriggerKey.isEmpty ? "add_11th_task" : upgradeTriggerKey, isPresented: $showingUpgradePrompt)
} }
@@ -489,9 +506,8 @@ private struct TasksSectionContainer: View {
showEditTask = true showEditTask = true
}, },
onCancelTask: { task in onCancelTask: { task in
taskViewModel.cancelTask(id: task.id) { _ in selectedTaskForCancel = task
reloadTasks() showCancelConfirmation = true
}
}, },
onUncancelTask: { taskId in onUncancelTask: { taskId in
taskViewModel.uncancelTask(id: taskId) { _ in taskViewModel.uncancelTask(id: taskId) { _ in

View File

@@ -76,11 +76,11 @@ struct AllTasksView: View {
Text(L10n.Tasks.archiveConfirm.replacingOccurrences(of: "this task", with: "\"\(task.title)\"")) Text(L10n.Tasks.archiveConfirm.replacingOccurrences(of: "this task", with: "\"\(task.title)\""))
} }
} }
.alert(L10n.Tasks.deleteTask, isPresented: $showCancelConfirmation) { .alert(L10n.Tasks.cancelTask, isPresented: $showCancelConfirmation) {
Button(L10n.Common.cancel, role: .cancel) { Button(L10n.Common.no, role: .cancel) {
selectedTaskForCancel = nil selectedTaskForCancel = nil
} }
Button(L10n.Tasks.archive, role: .destructive) { Button(L10n.Common.yes, role: .destructive) {
if let task = selectedTaskForCancel { if let task = selectedTaskForCancel {
taskViewModel.cancelTask(id: task.id) { _ in taskViewModel.cancelTask(id: task.id) { _ in
loadAllTasks() loadAllTasks()
@@ -89,9 +89,7 @@ struct AllTasksView: View {
} }
} }
} message: { } message: {
if let task = selectedTaskForCancel { Text(L10n.Tasks.cancelConfirm)
Text(L10n.Tasks.archiveConfirm.replacingOccurrences(of: "this task", with: "\"\(task.title)\""))
}
} }
.onChange(of: showAddTask) { isShowing in .onChange(of: showAddTask) { isShowing in
if !isShowing { if !isShowing {