feat: open assigned pulls from mobile search (Closes #785)
All checks were successful
CI / lint (pull_request) Successful in 1m31s
CI / build-release (pull_request) Successful in 5s
CI / release-candidate (pull_request) Has been skipped

This commit is contained in:
timmy 2026-08-14 00:25:07 +00:00
parent 70281bb56a
commit 20d4f1ef7e
2 changed files with 26 additions and 9 deletions

View File

@ -4358,7 +4358,7 @@
(detail.assignees?.length ? ' · assigned to ' + detail.assignees.join(', ') : '');
qs('#search-preview-body').innerHTML = renderMarkdown(detail.body || 'No description provided.');
qs('#open-search-result-gitea').href = safeSearchUrl(detail.url) || '#';
claimButton.hidden = !(detail.claimable || (detail.assigned_to_me && detail.kind === 'issue'));
claimButton.hidden = !(detail.claimable || detail.assigned_to_me);
claimButton.textContent = detail.assigned_to_me ? 'Open in My Work' : 'Assign to me';
claimButton.disabled = state.status === 'claiming';
startButton.hidden = !(detail.kind === 'issue' && (detail.reopenable ||
@ -4370,7 +4370,7 @@
(state.status === 'claiming' ? 'Assigning this issue to you…' :
(state.status === 'claimed' ? 'Assignment confirmed. Opening My Work…' :
(detail.claimable ? 'This issue is open and unassigned.' :
(detail.assigned_to_me ? 'This issue is already in My Work.' :
(detail.assigned_to_me ? 'This item is already in My Work.' :
(detail.reopenable ? 'Closed—reopen to resume.' : 'Read-only preview.')))));
}
const searchPreview = createSearchPreview({
@ -4424,10 +4424,10 @@
renderCommands(qs('#cmd-input').value);
qs('#cmd-input').focus();
}
async function openPreviewIssueInMyWork(detail) {
async function openPreviewWorkInMyWork(detail) {
await load();
const item = lastMyWork.find(candidate =>
candidate.kind === 'issue' && candidate.key === detail.repository + '#' + detail.number
candidate.kind === detail.kind && candidate.key === detail.repository + '#' + detail.number
);
if (!item) return false;
taskOverlayHistory.leave();
@ -4629,10 +4629,9 @@
try {
const claimed = searchPreviewDetail;
if (claimed.claimable) await searchPreview.claim(claimed);
const opened = await openPreviewIssueInMyWork(claimed);
const opened = await openPreviewWorkInMyWork(claimed);
if (!opened) {
qs('#search-preview-status').textContent =
'Assignment confirmed. Refresh My Work to open the issue.';
qs('#search-preview-status').textContent = 'Refresh My Work to open this item.';
}
} catch (error) {
qs('#search-preview-status').textContent = error.message + ' Retry assignment.';

View File

@ -297,9 +297,27 @@ def test_remote_search_selection_opens_native_preview_without_navigation():
def test_assigned_issue_preview_hands_off_to_existing_my_work_sheet():
html = dashboard_bundle_text()
assert "detail.claimable || (detail.assigned_to_me && detail.kind === 'issue')" in html
assert "claimButton.hidden = !(detail.claimable || detail.assigned_to_me)" in html
assert "claimButton.textContent = detail.assigned_to_me ? 'Open in My Work' : 'Assign to me'" in html
assert "openPreviewIssueInMyWork" in html
assert "openPreviewWorkInMyWork" in html
def test_assigned_pull_preview_hands_off_to_existing_my_work_sheet_without_claiming():
html = dashboard_bundle_text()
assert "claimButton.hidden = !(detail.claimable || detail.assigned_to_me)" in html
assert "async function openPreviewWorkInMyWork(detail)" in html
handoff = html.split("async function openPreviewWorkInMyWork(detail)", 1)[1].split(
"function runCommandItem", 1
)[0]
assert "candidate.kind === detail.kind" in handoff
assert "candidate.key === detail.repository + '#' + detail.number" in handoff
click_handler = html.split(
"qs('#claim-search-result').addEventListener('click'", 1
)[1].split("qs('#start-search-result')", 1)[0]
assert "if (claimed.claimable) await searchPreview.claim(claimed)" in click_handler
assert "await openPreviewWorkInMyWork(claimed)" in click_handler
def test_search_preview_offers_assign_and_start_for_eligible_issues():