|
60 | 60 | blocked: "Mark this task as blocked? The worker's claim is released.", |
61 | 61 | }; |
62 | 62 |
|
| 63 | + function withCompletionSummary(patch, count) { |
| 64 | + if (!patch || patch.status !== "done") return patch; |
| 65 | + const label = count && count > 1 ? `${count} selected task(s)` : "this task"; |
| 66 | + const value = window.prompt( |
| 67 | + `Completion summary for ${label}. This is stored as the task result.`, |
| 68 | + "", |
| 69 | + ); |
| 70 | + if (value === null) return null; |
| 71 | + const summary = value.trim(); |
| 72 | + if (!summary) { |
| 73 | + window.alert("Completion summary is required before marking a task done."); |
| 74 | + return null; |
| 75 | + } |
| 76 | + return Object.assign({}, patch, { result: summary, summary }); |
| 77 | + } |
| 78 | + |
63 | 79 | const API = "/api/plugins/kanban"; |
64 | 80 | const MIME_TASK = "text/x-hermes-task"; |
65 | 81 |
|
|
480 | 496 | const moveTask = useCallback(function (taskId, newStatus) { |
481 | 497 | const confirmMsg = DESTRUCTIVE_TRANSITIONS[newStatus]; |
482 | 498 | if (confirmMsg && !window.confirm(confirmMsg)) return; |
| 499 | + const patch = withCompletionSummary({ status: newStatus }, 1); |
| 500 | + if (!patch) return; |
483 | 501 | setBoardData(function (b) { |
484 | 502 | if (!b) return b; |
485 | 503 | let moved = null; |
|
499 | 517 | SDK.fetchJSON(withBoard(`${API}/tasks/${encodeURIComponent(taskId)}`, board), { |
500 | 518 | method: "PATCH", |
501 | 519 | headers: { "Content-Type": "application/json" }, |
502 | | - body: JSON.stringify({ status: newStatus }), |
| 520 | + body: JSON.stringify(patch), |
503 | 521 | }).catch(function (err) { |
504 | 522 | setError(`Move failed: ${err.message || err}`); |
505 | 523 | loadBoard(); |
|
538 | 556 | const applyBulk = useCallback(function (patch, confirmMsg) { |
539 | 557 | if (selectedIds.size === 0) return; |
540 | 558 | if (confirmMsg && !window.confirm(confirmMsg)) return; |
541 | | - const body = Object.assign({ ids: Array.from(selectedIds) }, patch); |
| 559 | + const finalPatch = withCompletionSummary(patch, selectedIds.size); |
| 560 | + if (!finalPatch) return; |
| 561 | + const body = Object.assign({ ids: Array.from(selectedIds) }, finalPatch); |
542 | 562 | SDK.fetchJSON(withBoard(`${API}/tasks/bulk`, board), { |
543 | 563 | method: "POST", |
544 | 564 | headers: { "Content-Type": "application/json" }, |
|
1426 | 1446 | if (opts && opts.confirm && !window.confirm(opts.confirm)) { |
1427 | 1447 | return Promise.resolve(); |
1428 | 1448 | } |
| 1449 | + const finalPatch = withCompletionSummary(patch, 1); |
| 1450 | + if (!finalPatch) return Promise.resolve(); |
1429 | 1451 | return SDK.fetchJSON(withBoard(`${API}/tasks/${encodeURIComponent(props.taskId)}`, boardSlug), { |
1430 | 1452 | method: "PATCH", |
1431 | 1453 | headers: { "Content-Type": "application/json" }, |
1432 | | - body: JSON.stringify(patch), |
| 1454 | + body: JSON.stringify(finalPatch), |
1433 | 1455 | }).then(function () { load(); props.onRefresh(); }); |
1434 | 1456 | }; |
1435 | 1457 |
|
|
0 commit comments