From 185f3f970672bbf60d714b5eeb52483b0a01d8c9 Mon Sep 17 00:00:00 2001 From: timmy Date: Tue, 25 Aug 2026 14:55:54 +0000 Subject: [PATCH] fix: close mobile week reschedule while saving Closes #1398 --- frontend/today-week-reschedule.js | 4 +-- tests/test_today_week_reschedule.py | 49 +++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/frontend/today-week-reschedule.js b/frontend/today-week-reschedule.js index 38cfa4d..750a522 100644 --- a/frontend/today-week-reschedule.js +++ b/frontend/today-week-reschedule.js @@ -337,10 +337,9 @@ function mountTodayWeekReschedule({ dialog.addEventListener('cancel',event=>{event.preventDefault();close();}); confirm.addEventListener('click',async()=>{ if(!selectedDate)return; - confirm.disabled=true;status.textContent='Moving Today into Week Ahead…'; + confirm.disabled=true;status.textContent='Moving Today into Week Ahead…';dialog.close(); try{ const result=await controller.confirm(selectedDate,Number(estimate.value),{allowOverload}); - dialog.close(); if(result.sync_pending){ announce('Moved locally. Saved on this device · sync pending.');warm(); }else{ @@ -348,6 +347,7 @@ function mountTodayWeekReschedule({ } await continueToday(); }catch(error){ + if(!dialog.open)dialog.showModal(); const overload=error.message.includes('Confirm overload');allowOverload=overload; status.textContent=error.message; confirm.textContent=overload?'Confirm overload & continue':'Move to Week Ahead & continue'; diff --git a/tests/test_today_week_reschedule.py b/tests/test_today_week_reschedule.py index 00babb4..f1a5c3d 100644 --- a/tests/test_today_week_reschedule.py +++ b/tests/test_today_week_reschedule.py @@ -326,6 +326,55 @@ console.log(JSON.stringify({message,adopted,pending:controller.pending(),remaini assert result["remaining"] == 1 +def test_reschedule_dialog_closes_as_soon_as_a_valid_move_is_confirmed(): + result = run_controller(""" +const mount=require('./frontend/today-week-reschedule.js').mount; +class Element { + constructor(){this.listeners={};this.dataset={};this.children=[];this.open=false;this.disabled=false;this.value='';this.textContent='';} + addEventListener(type,handler){(this.listeners[type] ||= []).push(handler);} + async emit(type,event={preventDefault(){}}){for(const handler of this.listeners[type]||[])await handler(event);} + append(...children){this.children.push(...children);} + replaceChildren(...children){this.children=children;} + querySelectorAll(selector){return selector==='button' ? this.children : [];} + querySelector(){return this.children.find(child=>!child.disabled)||null;} + setAttribute(){} + showModal(){this.open=true;} + close(){this.open=false;} + focus(){} + click(){return this.emit('click');} +} +const selectors={ + '#today-week-reschedule':new Element(), '#today-week-reschedule-days':new Element(), + '#today-week-reschedule-estimate':new Element(), '#today-week-reschedule-status':new Element(), + '#confirm-today-week-reschedule':new Element(), '[data-work-session-reschedule-week]':new Element(), + '#cancel-today-week-reschedule':new Element(), '[data-mobile-today-more]':new Element(), +}; +const document={hidden:false,addEventListener(){},createElement:()=>new Element()}; +const window={addEventListener(){},setTimeout(){}}; +let finishMove; +const move=new Promise(resolve=>{finishMove=resolve;}); +const today={revision:4,ids:['active'],estimates:{active:30}}; +const weekState={revision:7,offline_snapshot:false,days:[]}; +const week={load:async()=>weekState,review:()=>({days:[{ + plan_date:'2026-08-27',label:'Thu',ids:[],planned_minutes:0,capacity_minutes:90,eligible:true, +}]}),adopt(){}}; +const api=async(url)=>url==='api/v1/today' ? today : move; +mount({qs:selector=>selectors[selector],document,window,week,api,getToday:()=>today, + adoptToday(){},currentTarget:()=>({identity:'active'}),closeActions(){},refresh:async()=>{},warm(){}, + continueToday:async()=>{},announce(){},schedule:callback=>callback()}); +await selectors['[data-work-session-reschedule-week]'].emit('click'); +await selectors['#today-week-reschedule-days'].children[0].emit('click'); +const confirming=selectors['#confirm-today-week-reschedule'].emit('click'); +await Promise.resolve(); +const openWhileSaving=selectors['#today-week-reschedule'].open; +finishMove({today:{revision:5,ids:[],estimates:{}},week:{revision:8,days:[]}}); +await confirming; +console.log(JSON.stringify({openWhileSaving,openAfterSaving:selectors['#today-week-reschedule'].open})); +""") + + assert result == {"openWhileSaving": False, "openAfterSaving": False} + + def test_mobile_active_today_reschedule_dialog_is_touch_safe_and_wired_into_release_bundle(): index = INDEX.read_text() css = CSS.read_text()