feat: close completed delegated parent from Filed review (Closes #925)
This commit is contained in:
1 parent
40b124bc2c
commit
05b2f769e4
3 files changed
+116
-17
No files matched your search
+17
-13
@@ -3615,11 +3615,13 @@
|
||||
const button = qs('#complete-parent-and-acknowledge');
|
||||
button.hidden = false;
|
||||
button.disabled = false;
|
||||
button.textContent = relationship.alreadyCompleted ?
|
||||
'Parent complete · acknowledge' : 'Complete parent step & acknowledge';
|
||||
qs('#completed-filed-progress').textContent = relationship.alreadyCompleted ?
|
||||
'Parent checklist already reflects this outcome.' :
|
||||
'Delegated outcome ready · complete its parent checklist step.';
|
||||
button.textContent = relationship.checklistComplete ?
|
||||
'Complete & close parent · acknowledge' : relationship.alreadyCompleted ?
|
||||
'Parent complete · acknowledge' : 'Complete parent step & acknowledge';
|
||||
qs('#completed-filed-progress').textContent = relationship.checklistComplete ?
|
||||
'Delegated outcome completes the parent checklist. Confirm to close the parent.' :
|
||||
relationship.alreadyCompleted ? 'Parent checklist already reflects this outcome.' :
|
||||
'Delegated outcome ready · complete its parent checklist step.';
|
||||
}
|
||||
} catch (_error) {
|
||||
if (selectedIssue !== item) return;
|
||||
@@ -3709,21 +3711,23 @@
|
||||
qs('#complete-parent-and-acknowledge').addEventListener('click', async () => {
|
||||
if (!selectedIssue?.is_completed || !delegatedParentReview) return;
|
||||
const button = qs('#complete-parent-and-acknowledge');
|
||||
button.disabled = true;
|
||||
const { parentItem, parentDetail, relationship } = delegatedParentReview;
|
||||
if (relationship.checklistComplete && !window.confirm(
|
||||
'Complete the final checklist step and close ' + parentItem.key + '?'
|
||||
)) return;
|
||||
button.disabled = true;
|
||||
try {
|
||||
if (!relationship.alreadyCompleted) {
|
||||
const completion = issueController.completeDelegatedParentTask(parentDetail.body, selectedIssue.url);
|
||||
await issueController.updateContent(parentItem, {
|
||||
title:parentDetail.title, body:completion.body, expectedUpdatedAt:parentDetail.updated_at,
|
||||
});
|
||||
}
|
||||
await issueController.finishDelegatedParentReview({
|
||||
relationship, parentItem, parentDetail, childUrl:selectedIssue.url,
|
||||
updateContent:(item, payload) => issueController.updateContent(item, payload),
|
||||
closeParent:item => issueController.close(item),
|
||||
});
|
||||
acknowledgeCompletedFiled();
|
||||
} catch (error) {
|
||||
if (!selectedIssue) return;
|
||||
button.disabled = false;
|
||||
qs('#issue-sheet-status').textContent =
|
||||
'Parent step was not changed. Reload the parent relationship and retry. ' + error.message;
|
||||
'Parent review action did not finish. Reload the parent relationship and retry. ' + error.message;
|
||||
button.focus();
|
||||
}
|
||||
});
|
||||
|
||||
+37
-2
@@ -77,6 +77,21 @@ function manageChecklistTask(raw, targetIndex, operation = {}) {
|
||||
return parts.join('');
|
||||
}
|
||||
|
||||
function checklistIsComplete(raw) {
|
||||
const lines = String(raw || '').split(/(?:\r\n|\n|\r)/);
|
||||
let fenced = false;
|
||||
let found = false;
|
||||
for (const line of lines) {
|
||||
if (/^\s*```/.test(line)) { fenced = !fenced; continue; }
|
||||
if (fenced) continue;
|
||||
const task = line.match(/^\s*[-*+]\s+\[([ xX])\]\s+/);
|
||||
if (!task) continue;
|
||||
found = true;
|
||||
if (task[1].toLocaleLowerCase() !== 'x') return false;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
function completeDelegatedParentTask(raw, childUrl) {
|
||||
const url = String(childUrl || '');
|
||||
if (!/^https:\/\/[^\s)]+$/.test(url)) throw new Error('The delegated issue link is unavailable.');
|
||||
@@ -93,13 +108,27 @@ function completeDelegatedParentTask(raw, childUrl) {
|
||||
if (linkedTask?.[1] === url) {
|
||||
const alreadyCompleted = task[2].toLocaleLowerCase() === 'x';
|
||||
if (!alreadyCompleted) parts[index] = task[1] + 'x' + task[3];
|
||||
return { body:parts.join(''), taskIndex, alreadyCompleted };
|
||||
const body = parts.join('');
|
||||
return { body, taskIndex, alreadyCompleted, checklistComplete:checklistIsComplete(body) };
|
||||
}
|
||||
taskIndex += 1;
|
||||
}
|
||||
throw new Error('The parent checklist no longer links to this delegated issue.');
|
||||
}
|
||||
|
||||
async function finishDelegatedParentReview({ parentItem, parentDetail, childUrl, updateContent, closeParent }) {
|
||||
const completion = completeDelegatedParentTask(parentDetail?.body, childUrl);
|
||||
if (!completion.alreadyCompleted) {
|
||||
await updateContent(parentItem, {
|
||||
title:parentDetail.title,
|
||||
body:completion.body,
|
||||
expectedUpdatedAt:parentDetail.updated_at,
|
||||
});
|
||||
}
|
||||
if (completion.checklistComplete) await closeParent(parentItem);
|
||||
return { updated:!completion.alreadyCompleted, closed:completion.checklistComplete };
|
||||
}
|
||||
|
||||
function delegatedParentReference(childDetail) {
|
||||
const body = String(childDetail?.body || '');
|
||||
const match = body.match(/(?:^|\n)Related to \[([A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+)#([1-9]\d*)\]\((https:\/\/[^\s)]+)\)\.(?:\r?$|\s)/m);
|
||||
@@ -112,7 +141,12 @@ function resolveDelegatedParent(child, childDetail, parentDetail) {
|
||||
if (!parent) return null;
|
||||
try {
|
||||
const completion = completeDelegatedParentTask(parentDetail?.body, child?.url);
|
||||
return { parent, taskIndex:completion.taskIndex, alreadyCompleted:completion.alreadyCompleted };
|
||||
return {
|
||||
parent,
|
||||
taskIndex:completion.taskIndex,
|
||||
alreadyCompleted:completion.alreadyCompleted,
|
||||
checklistComplete:completion.checklistComplete,
|
||||
};
|
||||
} catch (_error) {
|
||||
return null;
|
||||
}
|
||||
@@ -630,6 +664,7 @@ createIssueSheet.createPlanningLoader = createPlanningLoader;
|
||||
|
||||
createIssueSheet.manageChecklistTask = manageChecklistTask;
|
||||
createIssueSheet.completeDelegatedParentTask = completeDelegatedParentTask;
|
||||
createIssueSheet.finishDelegatedParentReview = finishDelegatedParentReview;
|
||||
createIssueSheet.delegatedParentReference = delegatedParentReference;
|
||||
createIssueSheet.resolveDelegatedParent = resolveDelegatedParent;
|
||||
if (typeof module !== 'undefined' && module.exports) module.exports = createIssueSheet;
|
||||
Reference in new issue
Block a user