feat: unify mobile queue start and continue action (Closes #1450)
This commit is contained in:
1 parent
c2b7ce67d8
commit
9381ff9d84
7 files changed
+112
-17
No files matched your search
@@ -295,6 +295,25 @@ process.stdout.write(JSON.stringify({{first, ready, opened}}));
|
||||
}
|
||||
|
||||
|
||||
def test_start_day_view_can_render_status_without_own_action_button():
|
||||
script = f"""
|
||||
const createStartDay = require({json.dumps(str(START_DAY))});
|
||||
const elements = {{summary:{{textContent:''}}, phases:{{textContent:''}}}};
|
||||
const controller = createStartDay({{
|
||||
getCounts: () => ({{attention:2, today:3}}),
|
||||
openQueue: () => {{}},
|
||||
elements,
|
||||
}});
|
||||
controller.start();
|
||||
process.stdout.write(JSON.stringify({{summary:elements.summary.textContent, phases:elements.phases.textContent}}));
|
||||
"""
|
||||
|
||||
assert run_node(script) == {
|
||||
"summary": "2 items before Today · 3 planned",
|
||||
"phases": "Attention 2",
|
||||
}
|
||||
|
||||
|
||||
def test_prepare_today_pass_persists_per_account_and_hands_off_using_live_counts():
|
||||
script = f"""
|
||||
const createStartDay = require({json.dumps(str(START_DAY))});
|
||||
@@ -440,6 +459,22 @@ process.stdout.write(JSON.stringify(JSON.parse(saved.get('stackchain.mobile-star
|
||||
assert run_node(script) == {"login": "timmy", "day": "2026-08-15", "phase": "agenda"}
|
||||
|
||||
|
||||
@pytest.mark.anyio
|
||||
async def test_mobile_queues_render_one_adaptive_start_or_continue_action():
|
||||
html = await dashboard()
|
||||
|
||||
assert 'id="mobile-queue-next-heading">Start / Continue</p>' in html
|
||||
assert html.count('id="mobile-queue-next-action"') == 1
|
||||
assert 'id="mobile-start-day-action"' not in html
|
||||
assert "getPreparation: () =>" in html
|
||||
assert "openPreparation: () => mobileStartDay.startNext()" in html
|
||||
assert "action: qs('#mobile-start-day-action')" not in html
|
||||
assert "qs('#mobile-queue-next-action').focus();" in html
|
||||
assert "mobileStartDay.finish();" in html
|
||||
assert "renderMobileQueuePresentation();" in html
|
||||
assert "qs('#finish-mobile-start-day').addEventListener('click', () => {" in html
|
||||
|
||||
|
||||
@pytest.mark.anyio
|
||||
async def test_dashboard_wires_thumb_safe_start_day_briefing_into_offline_mobile_bundle():
|
||||
html = await dashboard()
|
||||
@@ -448,7 +483,7 @@ async def test_dashboard_wires_thumb_safe_start_day_briefing_into_offline_mobile
|
||||
assert 'class="mobile-start-day"' in html
|
||||
assert 'id="mobile-start-day-summary"' in html
|
||||
assert 'id="mobile-start-day-phases"' in html
|
||||
assert 'id="mobile-start-day-action"' in html
|
||||
assert 'id="mobile-queue-next-action"' in html
|
||||
assert 'id="finish-mobile-start-day"' in html
|
||||
assert '<script src="static/mobile-start-day.js"></script>' in html
|
||||
assert "const mobileStartDay = createMobileStartDay({" in html
|
||||
@@ -465,7 +500,7 @@ async def test_dashboard_wires_thumb_safe_start_day_briefing_into_offline_mobile
|
||||
assert "queueCounts.followingUnavailable ? followingQueue.open()" in html
|
||||
assert "Checking Agenda, Attention, Updates, Filed, and Following" in html
|
||||
assert "mobileStartDay.render();" in html
|
||||
assert ".mobile-start-day-action { width:100%; min-height:48px;" in html
|
||||
assert ".mobile-queue-next button { min-height:48px; width:100%;" in html
|
||||
assert ".mobile-start-day-finish { min-height:44px;" in html
|
||||
assert "max-width:100%; overflow-wrap:anywhere;" in html
|
||||
assert "BASE + 'static/mobile-start-day.js'" in service_worker
|
||||
@@ -481,7 +516,7 @@ async def test_primary_mobile_work_action_opens_a_unique_item_prepare_today_brie
|
||||
assert "function openMobileStartDay()" in html
|
||||
assert "qs('#mobile-queue-heading').textContent = state.active ? 'Resume Prepare Today' : 'Prepare Today';" in html
|
||||
assert "qs('#mobile-queue-sheet').showModal();" in html
|
||||
assert "qs('#mobile-start-day-action').focus();" in html
|
||||
assert "qs('#mobile-queue-next-action').focus();" in html
|
||||
assert "let preparationItems = {};" in html
|
||||
assert "getPhaseItems: () => preparationItems" in html
|
||||
assert "preparationItems = {" in html
|
||||
|
||||
@@ -752,6 +752,45 @@ process.stdout.write(JSON.stringify({{first, agenda, opened, fallback, calls}}))
|
||||
}
|
||||
|
||||
|
||||
def test_mobile_queue_launcher_uses_one_adaptive_action_for_daily_preparation():
|
||||
script = f"""
|
||||
const createLauncher = require({json.dumps(str(QUEUE_LAUNCHER))});
|
||||
const calls = [];
|
||||
let preparation = {{active:true, total:2, label:'Review Human Gates'}};
|
||||
const nextAction = {{textContent:'', dataset:{{}}, attributes:{{}}, setAttribute(name, value) {{ this.attributes[name]=value; }}}};
|
||||
const launcher = createLauncher({{
|
||||
getCounts: () => ({{delivery:4}}),
|
||||
getPreparation: () => preparation,
|
||||
openPreparation: () => calls.push('prepare'),
|
||||
nextAction,
|
||||
}});
|
||||
launcher.renderPresentation();
|
||||
const resumed = [nextAction.textContent, nextAction.dataset.queue, nextAction.attributes['aria-label']];
|
||||
launcher.continueWork();
|
||||
preparation = {{active:false, total:2, label:'Review Agenda'}};
|
||||
launcher.renderPresentation();
|
||||
const started = [nextAction.textContent, nextAction.dataset.queue, nextAction.attributes['aria-label']];
|
||||
launcher.continueWork();
|
||||
process.stdout.write(JSON.stringify({{resumed, started, calls}}));
|
||||
"""
|
||||
result = subprocess.run(["node", "-e", script], capture_output=True, text=True)
|
||||
|
||||
assert result.returncode == 0, result.stderr
|
||||
assert json.loads(result.stdout) == {
|
||||
"resumed": [
|
||||
"Resume preparation · Review Human Gates",
|
||||
"prepare",
|
||||
"Start or continue: Resume preparation · Review Human Gates",
|
||||
],
|
||||
"started": [
|
||||
"Start day · Review Agenda",
|
||||
"prepare",
|
||||
"Start or continue: Start day · Review Agenda",
|
||||
],
|
||||
"calls": ["prepare", "prepare"],
|
||||
}
|
||||
|
||||
|
||||
def test_mobile_queue_launcher_builds_truthful_next_up_and_active_sections():
|
||||
script = f"""
|
||||
const createLauncher = require({json.dumps(str(QUEUE_LAUNCHER))});
|
||||
|
||||
Reference in new issue
Block a user