Compare commits
No commits in common. "f8c5c2b0583daf08d8a3de8794ac5db9a9fd38ba" and "b214a49686158f468515d42b2ccd14845d82f978" have entirely different histories.
f8c5c2b058
...
b214a49686
|
|
@ -714,23 +714,11 @@
|
||||||
'Session recovery could not be saved on this device. You can keep working.';
|
'Session recovery could not be saved on this device. You can keep working.';
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
function updateDetailDeferLabels(active) {
|
|
||||||
document.querySelectorAll('[data-detail-defer-preset=today]').forEach(button => {
|
|
||||||
button.textContent = active ? 'Later today & next' : 'Later today';
|
|
||||||
});
|
|
||||||
document.querySelectorAll('[data-detail-defer-preset=tomorrow]').forEach(button => {
|
|
||||||
button.textContent = active ? 'Tomorrow & next' : 'Tomorrow';
|
|
||||||
});
|
|
||||||
document.querySelectorAll('[data-detail-defer-custom]').forEach(button => {
|
|
||||||
button.textContent = active ? 'Choose date & time & next' : 'Choose date & time';
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function updateWorkSessionActions() {
|
function updateWorkSessionActions() {
|
||||||
const active = workSession.active();
|
const active = workSession.active();
|
||||||
qs('#start-work-session').hidden = active;
|
qs('#start-work-session').hidden = active;
|
||||||
qs('#resume-today-session').hidden = active || !todayMyWork.length || !workSession.resumable();
|
qs('#resume-today-session').hidden = active || !todayMyWork.length || !workSession.resumable();
|
||||||
qs('#end-today-session').hidden = !active;
|
qs('#end-today-session').hidden = !active;
|
||||||
updateDetailDeferLabels(active);
|
|
||||||
mobileTaskDock.updateWork(mobileWorkEntry.mode(), countMyWork(activeMyWork).attention);
|
mobileTaskDock.updateWork(mobileWorkEntry.mode(), countMyWork(activeMyWork).attention);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1250,10 +1238,6 @@
|
||||||
const detailDefer = createDetailDefer({
|
const detailDefer = createDetailDefer({
|
||||||
laterWork,
|
laterWork,
|
||||||
session: workSession,
|
session: workSession,
|
||||||
continueSession: item => completeTodayItem(item, {
|
|
||||||
successMessage: 'Deferred to Later. Next Today item opened.',
|
|
||||||
failureMessage: 'Could not remove this item from Today.',
|
|
||||||
}),
|
|
||||||
close: () => workRoute.close(),
|
close: () => workRoute.close(),
|
||||||
refresh: refreshMyWorkView,
|
refresh: refreshMyWorkView,
|
||||||
focus: () => qs('[data-work-filter="' + selectedWorkFilter + '"]')?.focus(),
|
focus: () => qs('[data-work-filter="' + selectedWorkFilter + '"]')?.focus(),
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
function createDetailDefer({
|
function createDetailDefer({
|
||||||
laterWork,
|
laterWork,
|
||||||
session,
|
session,
|
||||||
continueSession = null,
|
|
||||||
close,
|
close,
|
||||||
refresh,
|
refresh,
|
||||||
focus,
|
focus,
|
||||||
|
|
@ -17,13 +16,6 @@ function createDetailDefer({
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const inSession = session.active();
|
const inSession = session.active();
|
||||||
if (continueSession && session.checkpointed?.(item)) {
|
|
||||||
if (continueSession(item) === true) return true;
|
|
||||||
laterWork.restore(item);
|
|
||||||
refresh();
|
|
||||||
announce('Could not remove this item from Today, so it was restored from Later.');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!inSession && closeSheet) close();
|
if (!inSession && closeSheet) close();
|
||||||
refresh();
|
refresh();
|
||||||
announce('Deferred until ' + formatTime(until) + '. It stays unread and unchanged in Gitea.');
|
announce('Deferred until ' + formatTime(until) + '. It stays unread and unchanged in Gitea.');
|
||||||
|
|
|
||||||
|
|
@ -1223,75 +1223,6 @@ process.stdout.write(JSON.stringify({{saved,calls}}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_detail_defer_completes_checkpointed_today_item_after_saving_later():
|
|
||||||
script = f"""
|
|
||||||
const createDetailDefer = require({json.dumps(str(DETAIL_DEFER))});
|
|
||||||
const calls = [];
|
|
||||||
const item = {{kind:'issue',repository:'stackchain/api',number:17,title:'Read first'}};
|
|
||||||
const controller = createDetailDefer({{
|
|
||||||
laterWork: {{
|
|
||||||
presetUntil:() => new Date('2026-08-09T09:00:00Z'),
|
|
||||||
defer:(saved, until) => {{ calls.push(['defer', saved.title, until.toISOString()]); return 'deferred'; }},
|
|
||||||
restore:() => calls.push(['restore']),
|
|
||||||
}},
|
|
||||||
session: {{active:() => true, checkpointed:saved => saved === item}},
|
|
||||||
continueSession:saved => {{ calls.push(['continue', saved.title]); return true; }},
|
|
||||||
close:() => calls.push(['close']), refresh:() => calls.push(['refresh']),
|
|
||||||
focus:() => calls.push(['focus']), announce:message => calls.push(['announce', message]),
|
|
||||||
}});
|
|
||||||
const saved = controller.defer(item, 'tomorrow');
|
|
||||||
process.stdout.write(JSON.stringify({{saved,calls}}));
|
|
||||||
"""
|
|
||||||
|
|
||||||
result = subprocess.run(
|
|
||||||
["node", "-e", script], check=True, capture_output=True, text=True
|
|
||||||
)
|
|
||||||
|
|
||||||
assert json.loads(result.stdout) == {
|
|
||||||
"saved": True,
|
|
||||||
"calls": [
|
|
||||||
["defer", "Read first", "2026-08-09T09:00:00.000Z"],
|
|
||||||
["continue", "Read first"],
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def test_detail_defer_rolls_back_later_when_today_cannot_be_removed():
|
|
||||||
script = f"""
|
|
||||||
const createDetailDefer = require({json.dumps(str(DETAIL_DEFER))});
|
|
||||||
const calls = [];
|
|
||||||
const item = {{kind:'issue',repository:'stackchain/api',number:17}};
|
|
||||||
const controller = createDetailDefer({{
|
|
||||||
laterWork: {{
|
|
||||||
presetUntil:() => new Date('2026-08-09T09:00:00Z'),
|
|
||||||
defer:() => {{ calls.push('defer'); return 'deferred'; }},
|
|
||||||
restore:saved => {{ calls.push(['restore', saved.number]); return true; }},
|
|
||||||
}},
|
|
||||||
session: {{active:() => true, checkpointed:() => true}},
|
|
||||||
continueSession:() => {{ calls.push('continue'); return false; }},
|
|
||||||
close:() => calls.push('close'), refresh:() => calls.push('refresh'),
|
|
||||||
focus:() => calls.push('focus'), announce:message => calls.push(['announce', message]),
|
|
||||||
}});
|
|
||||||
const saved = controller.defer(item, 'tomorrow');
|
|
||||||
process.stdout.write(JSON.stringify({{saved,calls}}));
|
|
||||||
"""
|
|
||||||
|
|
||||||
result = subprocess.run(
|
|
||||||
["node", "-e", script], check=True, capture_output=True, text=True
|
|
||||||
)
|
|
||||||
|
|
||||||
assert json.loads(result.stdout) == {
|
|
||||||
"saved": False,
|
|
||||||
"calls": [
|
|
||||||
"defer",
|
|
||||||
"continue",
|
|
||||||
["restore", 17],
|
|
||||||
"refresh",
|
|
||||||
["announce", "Could not remove this item from Today, so it was restored from Later."],
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.anyio
|
@pytest.mark.anyio
|
||||||
async def test_mobile_detail_sheets_offer_touch_safe_defer_without_a_gitea_mutation():
|
async def test_mobile_detail_sheets_offer_touch_safe_defer_without_a_gitea_mutation():
|
||||||
html = await dashboard()
|
html = await dashboard()
|
||||||
|
|
@ -1307,18 +1238,6 @@ async def test_mobile_detail_sheets_offer_touch_safe_defer_without_a_gitea_mutat
|
||||||
assert "fetch(" not in DETAIL_DEFER.read_text()
|
assert "fetch(" not in DETAIL_DEFER.read_text()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.anyio
|
|
||||||
async def test_checkpointed_detail_defer_completes_today_and_advertises_next_item():
|
|
||||||
html = await dashboard()
|
|
||||||
|
|
||||||
assert "continueSession: item => completeTodayItem(item, {" in html
|
|
||||||
assert "successMessage: 'Deferred to Later. Next Today item opened.'" in html
|
|
||||||
assert "advance: () => runTodayTransition('complete')" in html
|
|
||||||
assert "button.textContent = active ? 'Later today & next' : 'Later today'" in html
|
|
||||||
assert "button.textContent = active ? 'Tomorrow & next' : 'Tomorrow'" in html
|
|
||||||
assert "button.textContent = active ? 'Choose date & time & next' : 'Choose date & time'" in html
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.anyio
|
@pytest.mark.anyio
|
||||||
async def test_mobile_my_work_wires_touch_safe_non_mutating_later_actions():
|
async def test_mobile_my_work_wires_touch_safe_non_mutating_later_actions():
|
||||||
html = await dashboard()
|
html = await dashboard()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user