fix(#1212): require bulk completion evidence
This commit is contained in:
1 parent
9f16ba2929
commit
98c417ae84
4 files changed
+109
-7
No files matched your search
@@ -151,6 +151,7 @@ fun KanbanScreen(
|
||||
var isMultiSelectMode by remember { mutableStateOf(false) }
|
||||
var selectedTaskIds by remember { mutableStateOf(setOf<String>()) }
|
||||
var showBulkMoveDialog by remember { mutableStateOf(false) }
|
||||
var showBulkCompleteDialog by remember { mutableStateOf(false) }
|
||||
var showBulkAssignDialog by remember { mutableStateOf(false) }
|
||||
var showBulkDeleteDialog by remember { mutableStateOf(false) }
|
||||
|
||||
@@ -1052,9 +1053,13 @@ fun KanbanScreen(
|
||||
writableMoveColumns.forEach { col ->
|
||||
TextButton(
|
||||
onClick = {
|
||||
viewModel.bulkMove(selectedTaskIds.toList(), col.name) { failed ->
|
||||
selectedTaskIds = failed
|
||||
if (failed.isEmpty()) isMultiSelectMode = false
|
||||
if (col.name.equals("done", ignoreCase = true)) {
|
||||
showBulkCompleteDialog = true
|
||||
} else {
|
||||
viewModel.bulkMove(selectedTaskIds.toList(), col.name) { failed ->
|
||||
selectedTaskIds = failed
|
||||
if (failed.isEmpty()) isMultiSelectMode = false
|
||||
}
|
||||
}
|
||||
showBulkMoveDialog = false
|
||||
},
|
||||
@@ -1074,6 +1079,24 @@ fun KanbanScreen(
|
||||
)
|
||||
}
|
||||
|
||||
if (showBulkCompleteDialog) {
|
||||
BulkCompleteTasksDialog(
|
||||
taskCount = selectedTaskIds.size,
|
||||
onConfirm = { summary ->
|
||||
viewModel.bulkMove(
|
||||
taskIds = selectedTaskIds.toList(),
|
||||
targetStatus = "done",
|
||||
summary = summary,
|
||||
) { failed ->
|
||||
selectedTaskIds = failed
|
||||
if (failed.isEmpty()) isMultiSelectMode = false
|
||||
}
|
||||
showBulkCompleteDialog = false
|
||||
},
|
||||
onDismiss = { showBulkCompleteDialog = false },
|
||||
)
|
||||
}
|
||||
|
||||
if (showBulkAssignDialog) {
|
||||
AlertDialog(
|
||||
onDismissRequest = { showBulkAssignDialog = false },
|
||||
@@ -1431,6 +1454,43 @@ private fun CompleteTaskDialog(
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun BulkCompleteTasksDialog(
|
||||
taskCount: Int,
|
||||
onConfirm: (String) -> Unit,
|
||||
onDismiss: () -> Unit,
|
||||
) {
|
||||
var summary by remember { mutableStateOf("") }
|
||||
val trimmedSummary = summary.trim()
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismiss,
|
||||
title = { Text(stringResource(R.string.kanban_bulk_complete_title, taskCount)) },
|
||||
text = {
|
||||
OutlinedTextField(
|
||||
value = summary,
|
||||
onValueChange = { summary = it },
|
||||
label = { Text(stringResource(R.string.kanban_complete_summary_label)) },
|
||||
placeholder = { Text(stringResource(R.string.kanban_complete_summary_hint)) },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
minLines = 2,
|
||||
)
|
||||
},
|
||||
confirmButton = {
|
||||
Button(
|
||||
onClick = { onConfirm(trimmedSummary) },
|
||||
enabled = trimmedSummary.isNotEmpty(),
|
||||
) {
|
||||
Text(stringResource(R.string.kanban_action_complete))
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(onClick = onDismiss) {
|
||||
Text(stringResource(R.string.action_cancel))
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private fun KanbanTaskAction.labelRes(): Int =
|
||||
when (this) {
|
||||
KanbanTaskAction.TRIAGE -> R.string.kanban_action_triage
|
||||
|
||||
@@ -618,12 +618,26 @@ class KanbanViewModel(
|
||||
fun bulkMove(
|
||||
taskIds: List<String>,
|
||||
targetStatus: String,
|
||||
summary: String? = null,
|
||||
onComplete: ((failedIds: Set<String>) -> Unit)? = null,
|
||||
) {
|
||||
val board = _uiState.value.selectedBoard ?: return
|
||||
val completionSummary = summary?.trim()?.takeIf { it.isNotEmpty() }
|
||||
if (targetStatus.equals("done", ignoreCase = true) && completionSummary == null) {
|
||||
_uiState.update { it.copy(toastMessage = "Completion summary is required") }
|
||||
onComplete?.invoke(taskIds.toSet())
|
||||
return
|
||||
}
|
||||
viewModelScope.launch {
|
||||
_uiState.update { it.copy(isLoading = true) }
|
||||
when (val res = repository.bulkTasks(board.id, BulkTasksBody(ids = taskIds, status = targetStatus))) {
|
||||
val body =
|
||||
BulkTasksBody(
|
||||
ids = taskIds,
|
||||
status = targetStatus,
|
||||
summary = completionSummary,
|
||||
result = completionSummary,
|
||||
)
|
||||
when (val res = repository.bulkTasks(board.id, body)) {
|
||||
is NetworkResult.Success -> {
|
||||
val results = res.data.results
|
||||
val succeeded = results.filter { it.ok }.map { it.id }.toSet()
|
||||
|
||||
Reference in new issue
Block a user