feat: claim unowned work from Filed (Closes #893)
CI / lint (pull_request) Successful in 1m55s
CI / build-release (pull_request) Successful in 6s
CI / browser-journey (pull_request) Successful in 54s
CI / release-candidate (pull_request) Has been skipped

This commit is contained in:
timmy committed 2026-08-15 12:59:47 +00:00
1 parent 5105fb40d3
commit c594cc20fc
8 files changed
+117 -1

No files matched your search

+3
View File
@@ -539,6 +539,9 @@ textarea { resize: vertical; min-height: 120px; }
#issue-sheet.read-only .detail-defer,
#issue-sheet.read-only #issue-blockers,
#issue-sheet.read-only #retry-issue-comment-actions { display:none; }
.filed-claim-actions { position:sticky; bottom:0; z-index:4; box-sizing:border-box; width:min(560px,100%); display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:8px; margin-top:14px; padding:10px 4px calc(10px + env(safe-area-inset-bottom)); background:rgba(11,21,38,.98); border-top:1px solid #4ade80; }
.filed-claim-actions[hidden] { display:none; }
.filed-claim-actions button { min-width:0; min-height:44px; }
.issue-sheet-actions { position:sticky; bottom:0; z-index:3; display:grid; gap:8px; margin-top:14px; padding:10px 4px; padding-bottom:calc(10px + env(safe-area-inset-bottom)); background:rgba(11,21,38,.98); border-top:1px solid #2a496e; }
.issue-sheet-actions button, .issue-sheet-actions a { min-height:44px; display:flex; align-items:center; justify-content:center; }
.issue-sheet-actions a { border:1px solid #60a5fa; border-radius:10px; font-weight:700; }
+55
View File
@@ -1799,6 +1799,35 @@
},
});
const filedAssignAndStart = createAssignAndStart({
available: createAndStart.available,
claim: item => findWorkController.claim(item),
start: confirmed => {
const claimed = acceptClaimedIssue(confirmed);
closeIssueSheet(false);
refreshMyWorkView();
return createAndStart.complete(claimed);
},
queue: confirmed => {
const claimed = acceptClaimedIssue(confirmed);
const outcome = queueToday(claimed);
closeIssueSheet(false);
refreshMyWorkView();
openRoutedWork(claimed, qs('#my-work'));
return outcome;
},
recover: confirmed => {
const claimed = acceptClaimedIssue(confirmed);
closeIssueSheet(false);
refreshMyWorkView();
openRoutedWork(claimed, qs('#my-work'));
},
announce: message => {
qs('#issue-sheet-status').textContent = message;
qs('#my-work-action-status').textContent = message;
},
});
const batchFindWork = createBatchFindWork({
capacity: () => Math.max(0, todayWork.limit - todayWork.read().length),
owner:()=>planningOwnerLogin,timeBudget:()=>{
@@ -3373,6 +3402,9 @@
candidate.repository === item.repository && candidate.number === item.number
);
qs('#completed-filed-actions').hidden = !item.is_completed;
qs('#filed-claim-actions').hidden = true;
qs('#queue-filed-issue').disabled = true;
qs('#start-filed-issue').disabled = true;
qs('#completed-filed-progress').textContent = item.is_completed ?
'Completed Filed issue ' + (completedPosition + 1) + ' of ' + completedItems.length : '';
qs('#issue-sheet-body').textContent = '';
@@ -3432,6 +3464,10 @@
).join(' ');
qs('#issue-assignees').textContent = (detail.assignees || []).length ?
'Assigned to ' + detail.assignees.join(', ') : 'No assignee reported';
const claimableFiling = !offlineDetail && filedClaimEligible(item, detail);
qs('#filed-claim-actions').hidden = !claimableFiling;
qs('#queue-filed-issue').disabled = !claimableFiling;
qs('#start-filed-issue').disabled = !claimableFiling;
if (readOnly) paintIssueConversation(issueConversation.snapshot(), null);
else renderIssueConversation(issueConversation.snapshot());
qs('#open-issue-gitea').href = detail.url || item.url || '#';
@@ -5481,6 +5517,25 @@
}
});
qs('#close-issue-sheet').addEventListener('click', closeIssueSheet);
function runFiledClaim(destination) {
const item = selectedIssue;
if (!item || !selectedIssueDetail || !filedClaimEligible(item, selectedIssueDetail)) return;
qs('#queue-filed-issue').disabled = true;
qs('#start-filed-issue').disabled = true;
const request = destination === 'queue' ?
filedAssignAndStart.run(item, { destination:'queue' }) : filedAssignAndStart.run(item);
request.catch(error => {
if (selectedIssue !== item) return;
qs('#issue-sheet-status').textContent = 'Claim failed; this issue is still in Filed. ' + error.message + ' Retry.';
}).finally(() => {
if (selectedIssue === item && filedClaimEligible(item, selectedIssueDetail)) {
qs('#queue-filed-issue').disabled = false;
qs('#start-filed-issue').disabled = false;
}
});
}
qs('#queue-filed-issue').addEventListener('click', () => runFiledClaim('queue'));
qs('#start-filed-issue').addEventListener('click', () => runFiledClaim('start'));
qs('#retry-issue-load').addEventListener('click', () => {
if (selectedIssue) openIssueSheet(selectedIssue, issueTrigger);
});
+9
View File
@@ -0,0 +1,9 @@
function filedClaimEligible(item, detail) {
return Boolean(
item?.is_filed && !item?.is_assigned && !item?.is_completed &&
item?.state === 'open' && detail?.state === 'open' &&
Array.isArray(detail?.assignees) && detail.assignees.length === 0
);
}
if (typeof module !== 'undefined' && module.exports) module.exports = filedClaimEligible;
+5
View File
@@ -698,6 +698,10 @@
<div id="issue-handoff-status" class="small" aria-live="assertive">Load teammates to transfer ownership.</div>
</div>
</details>
<section class="filed-claim-actions" id="filed-claim-actions" aria-label="Take ownership of filed issue" hidden>
<button id="queue-filed-issue" type="button">Queue Today</button>
<button id="start-filed-issue" type="button">Claim &amp; start</button>
</section>
<div class="issue-sheet-actions">
<button class="share-work-route" type="button">Share</button>
<button id="release-issue" type="button">Release assignment</button>
@@ -1307,6 +1311,7 @@
<script src="static/create-issue-sheet.js"></script>
<script src="static/create-and-start.js"></script>
<script src="static/assign-and-start.js"></script>
<script src="static/filed-claim.js"></script>
<script src="static/queue-today.js"></script>
<script src="static/pull-sheet.js"></script>
<script src="static/review-sheet.js"></script>
+1
View File
@@ -76,6 +76,7 @@ const SHELL = [
BASE + 'static/create-issue-sheet.js',
BASE + 'static/create-and-start.js',
BASE + 'static/assign-and-start.js',
BASE + 'static/filed-claim.js',
BASE + 'static/queue-today.js',
BASE + 'static/pull-sheet.js',
BASE + 'static/review-sheet.js',