Fix iPhone offer template flicker (#33)
Avoid rebuilding the offer template picker during the five-second maintenance pass unless the selected template or template list actually changed. Includes a regression test for repeated maintenance cycles.
This commit is contained in:
parent
b99bb30aa1
commit
ee70c66ed8
@ -176,7 +176,18 @@
|
||||
if(!box){box=document.createElement('section');box.id='sunOfferTemplateV1764';box.className='sun-v1764-offer-template';const head=dialog.querySelector('.sun-offer-modal-head');if(head)head.insertAdjacentElement('afterend',box);else dialog.prepend(box);box.addEventListener('click',e=>{const b=e.target.closest('[data-v1764-offer-template]');if(!b)return;const id=b.dataset.v1764OfferTemplate;if(!persistOfferTemplate(activeOfferOrderId,id))return;renderOfferPicker();toast(`Оформление «${templateList().find(x=>x.id===id)?.name||id}» сохранено для этого предложения.`,'success',3200)});}
|
||||
renderOfferPicker();return true;
|
||||
}
|
||||
function renderOfferPicker(){const box=$('sunOfferTemplateV1764');if(box)box.innerHTML=pickerHtml()}
|
||||
function offerPickerSignature(){
|
||||
const list=templateList(),current=activeTemplateId();
|
||||
return JSON.stringify({current,templates:list.map(t=>[String(t?.id||''),String(t?.name||'')])});
|
||||
}
|
||||
function renderOfferPicker({force=false}={}){
|
||||
const box=$('sunOfferTemplateV1764');if(!box)return false;
|
||||
const signature=offerPickerSignature();
|
||||
if(!force&&box.dataset.sunV1764Signature===signature)return false;
|
||||
box.innerHTML=pickerHtml();
|
||||
box.dataset.sunV1764Signature=signature;
|
||||
return true;
|
||||
}
|
||||
function setActiveOffer(id){if(id==null||id==='')return;activeOfferOrderId=String(id);setTimeout(ensureOfferPicker,0)}
|
||||
function clearActiveOffer(){activeOfferOrderId=null}
|
||||
function patchOfferOpenExports(){
|
||||
|
||||
@ -118,6 +118,46 @@ test('a delayed menu editor cannot move back into a section that was already lef
|
||||
await expect(page.locator('#editor')).not.toHaveClass(/\bon\b/);
|
||||
});
|
||||
|
||||
|
||||
test('offer template picker is not rebuilt by the five-second maintenance timer',async({page})=>{
|
||||
await fixture(page,'<button id="offerOpen" data-sun-offer-id="one">Предложение</button><div id="sunClientOfferModal" class="modal on"><div class="dialog"><div class="sun-offer-modal-head"></div></div></div>');
|
||||
await page.evaluate(()=>{
|
||||
localStorage.setItem('sunOrders',JSON.stringify([{id:'one',clientOfferTemplateId:'light'}]));
|
||||
window.SunOfferTemplate={
|
||||
get:()=>({id:'light',template:{id:'light',name:'Светлый'}}),
|
||||
list:()=>[{id:'light',name:'Светлый'},{id:'editorial-grid',name:'Редакционный'}]
|
||||
};
|
||||
window.CateriumProposalPDF={resolveTemplate:id=>id,IDS:[]};
|
||||
window.sunOpenClientOffer=()=>{};
|
||||
window.sunOpenCurrentClientOffer=()=>{};
|
||||
});
|
||||
await page.addScriptTag({url:'/core/ux-fixes-v1764.js'});
|
||||
await page.locator('#offerOpen').click();
|
||||
const picker=page.locator('#sunOfferTemplateV1764');
|
||||
await expect(picker).toBeVisible();
|
||||
await expect(picker.locator('[data-v1764-offer-template]')).toHaveCount(2);
|
||||
const before=await picker.evaluate(el=>({
|
||||
first:el.querySelector('[data-v1764-offer-template]'),
|
||||
html:el.innerHTML,
|
||||
signature:el.dataset.sunV1764Signature
|
||||
}));
|
||||
await page.evaluate(()=>{
|
||||
const picker=document.getElementById('sunOfferTemplateV1764');
|
||||
window.offerPickerMutations=0;
|
||||
new MutationObserver(records=>{window.offerPickerMutations+=records.filter(r=>r.type==='childList').length}).observe(picker,{childList:true,subtree:true});
|
||||
});
|
||||
await page.waitForTimeout(5300);
|
||||
expect(await page.evaluate(()=>window.offerPickerMutations)).toBe(0);
|
||||
expect(await picker.evaluate((el,before)=>el.innerHTML===before.html&&el.dataset.sunV1764Signature===before.signature,before)).toBe(true);
|
||||
await picker.locator('[data-v1764-offer-template="editorial-grid"]').click();
|
||||
await expect(picker.locator('[data-v1764-offer-template="editorial-grid"]')).toHaveClass(/\bon\b/);
|
||||
const afterSelection=await page.evaluate(()=>window.offerPickerMutations);
|
||||
expect(afterSelection).toBeGreaterThan(0);
|
||||
await page.evaluate(()=>window.offerPickerMutations=0);
|
||||
await page.waitForTimeout(5300);
|
||||
expect(await page.evaluate(()=>window.offerPickerMutations)).toBe(0);
|
||||
});
|
||||
|
||||
test('full app stays stable across settings, menu, calendar and delayed background refreshes',async({page})=>{
|
||||
const errors=[];page.on('pageerror',e=>errors.push(String(e)));
|
||||
const workspaceId='22222222-2222-4222-8222-222222222222',servedRpcs=new Set();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user