{h.created_at} · autor #{h.actor_id} · {h.action} · {d.reason||'Sem fundamento registado no evento antigo'}{d.before_modules&&<> · antes: {names(d.before_modules)} · depois: {names(d.after_modules)}>}
;})}
:
Sem eventos anteriores.
};
}
export default function ModuleRecordsWorkspace(props) { return ; }
function Queue({context,can,api}) {
const areas=Object.keys(labels).filter(a=>can(`${a}.view`,a.endsWith('_drafts')?context.unit?.id??null:null)&&(!a.endsWith('_drafts')||context.unit));
const [area,setArea]=useState(areas[0]||'clients'),[state,setState]=useState('pending'),[search,setSearch]=useState(''),[query,setQuery]=useState(''),[page,setPage]=useState(1);
const [data,setData]=useState(null),[error,setError]=useState(''),[busy,setBusy]=useState(false),[loading,setLoading]=useState(false),[review,setReview]=useState(null),[message,setMessage]=useState(''),[refresh,setRefresh]=useState(0);
const generation=useRef(0);
useEffect(()=>{const current=++generation.current;setLoading(true);setData(null);setReview(null);setError('');
const params=new URLSearchParams({area,state,search:query,page:String(page),per_page:'25'});
api(`/api/module-records?${params}`).then(result=>{if(current===generation.current)setData(result);}).catch(e=>{if(current===generation.current)setError(e.message);}).finally(()=>{if(current===generation.current)setLoading(false);});
return ()=>{generation.current++;};
},[context.token,area,state,query,page,refresh]);
async function preview(e,row){e.preventDefault();setBusy(true);setError('');setMessage('');setReview(null);const current=generation.current;
try{const result=await api('/api/module-records/preview','POST',{area,id:row.id,version:row.version,...Object.fromEntries(new FormData(e.currentTarget))});if(current===generation.current)setReview(result);}catch(e){setError(e.message);}finally{setBusy(false);}}
async function confirm(){setBusy(true);setError('');try{const result=await api('/api/module-records','POST',{review_token:review.review_token});setReview(null);setMessage(result.replayed?'Decisão já registada; repetição reconhecida sem duplicação.':'Decisão individual registada. Dependências preservadas.');setRefresh(n=>n+1);}catch(e){setError(`${e.message} Pode repetir a confirmação se a resposta se perdeu; se o servidor indicar mudança, cancele e faça nova conferência.`);}finally{setBusy(false);}}
function reset(set,value){set(value);setPage(1);setReview(null);}
return
Conferência de associações de módulos
Opções gerais da empresa. Apenas registos do âmbito autorizado; os rascunhos pertencem à unidade activa: {context.unit?.name||'nenhuma seleccionada'}.
Cada decisão é individual e auditada. Não altera direitos, documentos ou responsabilidade financeira e não associa dependências automaticamente.
{error&&
{error}
}{message&&
{message}
}
{loading&&
A carregar…
}{data&&<>
{data.pagination.total} registos · página {data.pagination.page} de {data.pagination.last_page}