feat: assign and start available work (#411)
This commit is contained in:
1 parent
985472eb06
commit
4afe4dd3b9
7 files changed
+229
-7
No files matched your search
@@ -0,0 +1,29 @@
|
||||
function createAssignAndStart({ available, claim, start, recover, announce }) {
|
||||
let request = null;
|
||||
|
||||
function run(item) {
|
||||
if (request) return request;
|
||||
if (!available()) {
|
||||
announce('Today is full—remove an item before assigning this issue.');
|
||||
return Promise.resolve('full');
|
||||
}
|
||||
request = Promise.resolve()
|
||||
.then(() => claim(item))
|
||||
.then(confirmed => {
|
||||
const outcome = start(confirmed);
|
||||
if (outcome === 'started') {
|
||||
announce('Assigned, added to Today, and ready to work.');
|
||||
return outcome;
|
||||
}
|
||||
announce('Assigned to you, but Today could not start. The issue is open so you can recover.');
|
||||
recover(confirmed);
|
||||
return 'recovery';
|
||||
})
|
||||
.finally(() => { request = null; });
|
||||
return request;
|
||||
}
|
||||
|
||||
return { run };
|
||||
}
|
||||
|
||||
if (typeof module !== 'undefined' && module.exports) module.exports = createAssignAndStart;
|
||||
@@ -263,6 +263,7 @@ textarea { resize: vertical; min-height: 120px; }
|
||||
.find-work-list { display:grid; gap:10px; }
|
||||
.find-work-card { display:grid; gap:8px; padding:12px; border:1px solid #2a496e; border-radius:12px; background:#101f36; overflow-wrap:anywhere; }
|
||||
.find-work-card button { width:100%; font-weight:700; }
|
||||
.find-work-claim-actions { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:8px; }
|
||||
.find-work-detail { min-width:0; display:grid; gap:10px; padding:10px; border-radius:10px; background:#0b1526; }
|
||||
.find-work-description { margin:0; white-space:pre-wrap; overflow-wrap:anywhere; }
|
||||
.find-work-detail a { display:flex; align-items:center; justify-content:center; border:1px solid #60a5fa; border-radius:10px; font-weight:700; }
|
||||
|
||||
+52
-7
@@ -757,6 +757,38 @@
|
||||
announce: message => { qs('#my-work-action-status').textContent = message; },
|
||||
});
|
||||
|
||||
function acceptClaimedIssue(confirmed) {
|
||||
lastContextSnapshot = lastContextSnapshot || { user: {}, repos: [], issues: [], pull_requests: [] };
|
||||
lastContextSnapshot.issues = [confirmed].concat((lastContextSnapshot.issues || []).filter(candidate =>
|
||||
candidate.repository !== confirmed.repository || candidate.number !== confirmed.number
|
||||
));
|
||||
lastMyWork = buildMyWork(lastContextSnapshot);
|
||||
return lastMyWork.find(work =>
|
||||
work.kind === 'issue' && work.repository === confirmed.repository && work.number === confirmed.number
|
||||
);
|
||||
}
|
||||
|
||||
const assignAndStart = createAssignAndStart({
|
||||
available: createAndStart.available,
|
||||
claim: item => findWorkController.claim(item),
|
||||
start: confirmed => {
|
||||
const claimed = acceptClaimedIssue(confirmed);
|
||||
taskOverlayHistory.leave();
|
||||
refreshMyWorkView();
|
||||
return createAndStart.complete(claimed);
|
||||
},
|
||||
recover: confirmed => {
|
||||
const claimed = acceptClaimedIssue(confirmed);
|
||||
taskOverlayHistory.leave();
|
||||
refreshMyWorkView();
|
||||
openRoutedWork(claimed, qs('#find-work'));
|
||||
},
|
||||
announce: message => {
|
||||
qs('#find-work-status').textContent = message;
|
||||
qs('#my-work-action-status').textContent = message;
|
||||
},
|
||||
});
|
||||
|
||||
let planTodayTrigger = null;
|
||||
function planTodayItemMarkup(item, selected, index = -1) {
|
||||
const id = todayWork.identity(item);
|
||||
@@ -1869,7 +1901,9 @@
|
||||
'<div>' + (item.labels || []).map(label => '<span class="pill">' + escapeHtml(label) + '</span>').join(' ') +
|
||||
'</div><button type="button" data-preview-index="' + index + '" aria-expanded="' + expanded +
|
||||
'" aria-controls="' + detailId + '">' + (expanded ? 'Hide details' : 'View details') + '</button>' +
|
||||
detail + '<button type="button" data-claim-index="' + index + '">Assign to me</button></article>';
|
||||
detail + '<div class="find-work-claim-actions"><button type="button" data-claim-index="' + index +
|
||||
'">Assign to me</button><button type="button" data-claim-start-index="' + index +
|
||||
'">Assign & start</button></div></article>';
|
||||
}).join('') : '<div class="muted">No unassigned issues are available on this page.</div>';
|
||||
list.querySelectorAll('[data-preview-index]').forEach(button => {
|
||||
button.addEventListener('click', () => {
|
||||
@@ -1889,12 +1923,7 @@
|
||||
button.disabled = true;
|
||||
try {
|
||||
const confirmed = await findWorkController.claim(item);
|
||||
lastContextSnapshot = lastContextSnapshot || { user: {}, repos: [], issues: [], pull_requests: [] };
|
||||
lastContextSnapshot.issues = [confirmed].concat(lastContextSnapshot.issues || []);
|
||||
lastMyWork = buildMyWork(lastContextSnapshot);
|
||||
const claimed = lastMyWork.find(work =>
|
||||
work.kind === 'issue' && work.repository === confirmed.repository && work.number === confirmed.number
|
||||
);
|
||||
const claimed = acceptClaimedIssue(confirmed);
|
||||
taskOverlayHistory.leave();
|
||||
refreshMyWorkView();
|
||||
qs('#my-work-action-status').textContent = confirmed.repository + '#' + confirmed.number + ' assigned to you.';
|
||||
@@ -1906,6 +1935,22 @@
|
||||
}
|
||||
});
|
||||
});
|
||||
list.querySelectorAll('[data-claim-start-index]').forEach(button => {
|
||||
button.addEventListener('click', async () => {
|
||||
const item = findWorkController.items()[Number(button.dataset.claimStartIndex)];
|
||||
if (!item) return;
|
||||
const claimButtons = button.closest('.find-work-card')
|
||||
.querySelectorAll('[data-claim-index], [data-claim-start-index]');
|
||||
claimButtons.forEach(action => { action.disabled = true; });
|
||||
try {
|
||||
await assignAndStart.run(item);
|
||||
} catch (error) {
|
||||
qs('#find-work-status').textContent = error.message + ' Nothing was added to Today; retry assignment.';
|
||||
claimButtons.forEach(action => { action.disabled = false; });
|
||||
button.focus();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function openFindWorkSheet(navigate = true) {
|
||||
|
||||
@@ -606,6 +606,7 @@
|
||||
<script src="static/issue-sheet.js"></script>
|
||||
<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/pull-sheet.js"></script>
|
||||
<script src="static/review-sheet.js"></script>
|
||||
<script src="static/work-route.js"></script>
|
||||
|
||||
@@ -40,6 +40,7 @@ const SHELL = [
|
||||
BASE + 'static/issue-sheet.js',
|
||||
BASE + 'static/create-issue-sheet.js',
|
||||
BASE + 'static/create-and-start.js',
|
||||
BASE + 'static/assign-and-start.js',
|
||||
BASE + 'static/pull-sheet.js',
|
||||
BASE + 'static/review-sheet.js',
|
||||
BASE + 'static/work-route.js',
|
||||
|
||||
Reference in new issue
Block a user