Files
SGF/public/purchasing-exit.mjs
2026-11-04 09:37:20 +02:00

21 lines
2.2 KiB
JavaScript

/** Guard navigation between functions without saving or repeating a business command. */
export function installPurchasingExit(doc,win){
const dirty=new Map();let pending=0,active=null;
const message=text=>{const target=doc.querySelector('#status')??doc.querySelector('#message');if(target)target.textContent=text;};
const prune=()=>{for(const form of dirty.keys())if(!form.isConnected)dirty.delete(form);};
doc.addEventListener('input',event=>{const form=event.target.closest('form');if(event.isTrusted&&form&&form.id!=='filters'&&form.closest('main'))dirty.set(form,(dirty.get(form)??0)+1);});
doc.addEventListener('click',event=>{
active=event.target.closest('form');if(event.isTrusted&&active&&/^(Adicionar linha|Retirar linha)$/.test(event.target.textContent))dirty.set(active,(dirty.get(active)??0)+1);const link=event.target.closest('a[href]');if(!link)return;prune();
if(pending){event.preventDefault();message('Aguarde a conclusão da conferência ou confirmação antes de sair.');return;}
if(dirty.size){if(!win.confirm('Existem campos por confirmar. Sair descarta esses campos. Continuar?'))event.preventDefault();else dirty.clear();}
},true);
win.addEventListener('beforeunload',event=>{prune();if(dirty.size||pending){event.preventDefault();event.returnValue='';}});
const fetch=win.fetch.bind(win);win.fetch=async(url,options={})=>{
const writing=options.method==='POST'&&typeof url==='string'&&url.startsWith('/api/purchasing-'),final=writing&&/\/(confirm|issue)$/.test(url),form=active,version=form&&dirty.get(form),fields=final&&form?[...form.querySelectorAll('input,select,textarea,button')].map(e=>[e,e.disabled]):[];if(writing)pending++;for(const [field]of fields)field.disabled=true;
try{const response=await fetch(url,options);let complete=false;if(writing){try{await response.clone().json();complete=true;}catch{/* Uncertain response keeps the fields/preview available for manual recovery. */}}if(final&&complete&&response.ok&&form&&dirty.get(form)===version)dirty.delete(form);return response;}
finally{for(const [field,disabled]of fields)field.disabled=disabled;if(writing)pending--;}
};
return {dirty,pending:()=>pending};
}
if(typeof document!=='undefined'&&typeof window!=='undefined')installPurchasingExit(document,window);