From 6dea5fd1ef09fae500636d2068f0311605ca6951 Mon Sep 17 00:00:00 2001 From: timmy Date: Sun, 9 Aug 2026 10:12:55 +0000 Subject: [PATCH] feat: close issues and continue Today session (#391) --- frontend/dashboard.js | 15 +++++++++++---- tests/test_my_work.py | 18 ++++++++++++++++++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/frontend/dashboard.js b/frontend/dashboard.js index 824b9dd..d8b27bc 100644 --- a/frontend/dashboard.js +++ b/frontend/dashboard.js @@ -981,7 +981,7 @@ ); } - function refreshMyWorkView() { + function refreshMyWorkView({ reconcileSession = true } = {}) { lastDrafts = listDrafts(); const partitioned = laterWork.partition(lastMyWork, { pruneMissing: !Object.values(workPagination).some(page => page?.has_more), @@ -1040,7 +1040,7 @@ 'No assigned work, review requests, or unread updates.'; updateWorkPaginationControls(); renderMyWork(); - if (workSession.active()) workSession.reconcile(); + if (reconcileSession && workSession.active()) workSession.reconcile(); } function activeWorkStreams() { @@ -1528,6 +1528,7 @@ qs('#issue-edit-form').hidden = true; qs('#issue-edit-status').textContent = ''; qs('#close-issue').disabled = false; + qs('#close-issue').textContent = workSession.active() ? 'Close & next' : 'Close issue'; qs('#close-issue-sheet').focus(); try { const detail = offlineDetail || await issueController.load(item); @@ -3139,8 +3140,14 @@ lastMyWork = lastMyWork.filter(item => !(item.kind === 'issue' && item.repository === closing.repository && item.number === closing.number) ); - refreshMyWorkView(); - qs('#my-work-action-status').textContent = closing.key + ' closed.'; + refreshMyWorkView({ reconcileSession:false }); + const continuingSession = workSession.active(); + if (workSession.active()) workSession.complete(); + if (continuingSession && workSession.active()) { + qs('#my-work-action-status').textContent = closing.key + ' closed. Next work item opened.'; + } else if (!continuingSession) { + qs('#my-work-action-status').textContent = closing.key + ' closed.'; + } } catch (error) { qs('#issue-sheet-status').textContent = error.message + ' The issue remains in My Work; retry.'; button.disabled = false; diff --git a/tests/test_my_work.py b/tests/test_my_work.py index 4124f2a..b49e01e 100644 --- a/tests/test_my_work.py +++ b/tests/test_my_work.py @@ -1376,6 +1376,24 @@ async def test_dashboard_wires_work_session_to_existing_sheet_flows_and_completi assert opener in html +@pytest.mark.anyio +async def test_closing_issue_advances_active_session_once_and_exposes_close_and_next(): + html = await dashboard() + + assert "qs('#close-issue').textContent = workSession.active() ? 'Close & next' : 'Close issue';" in html + close_handler = html.split("qs('#close-issue').addEventListener('click'", 1)[1].split( + "qs('#close-pull-sheet').addEventListener", 1 + )[0] + assert "refreshMyWorkView({ reconcileSession:false });" in close_handler + assert "if (workSession.active()) workSession.complete();" in close_handler + assert close_handler.index("await issueController.close(selectedIssue)") < close_handler.index( + "if (workSession.active()) workSession.complete();" + ) + assert close_handler.index("lastMyWork = lastMyWork.filter") < close_handler.index( + "if (workSession.active()) workSession.complete();" + ) + + def test_work_session_can_start_at_a_newly_created_item(): script = f""" const buildMyWork = require({json.dumps(str(MY_WORK))});