FIELD ISSUES CONTROL

Carregando dados...
`; const w=window.open('','_blank'); w.document.write(html); w.document.close(); } // ====================== ETAPAS 8D — VERIFICAÇÃO ====================== const V8D_LISTS = ['v8dCkD3qc','v8dCkD3proc','v8dCkD56','v8dCkD78']; function v8dAddRef(listId, text='', status='', data='', responsavel=''){ const wrap = document.getElementById(listId); if(!wrap) return; const div = document.createElement('div'); div.className = 'v8d-ref-item'; div.innerHTML = `
`; wrap.appendChild(div); if(!text) div.querySelector('input[type=text]').focus(); } function v8dRefToggle(btn, val){ const item = btn.closest('.v8d-ref-item') || btn.closest('.v8d-check-item'); const sim = item.querySelector('.v8d-ref-sim'); const nao = item.querySelector('.v8d-ref-nao'); const current = sim.classList.contains('active')?'sim': nao.classList.contains('active')?'nao':''; sim.classList.remove('active'); nao.classList.remove('active'); if(current !== val){ if(val==='sim') sim.classList.add('active'); else nao.classList.add('active'); } } function v8dAddCheck(listId, text='', checked=false, status='', data='', responsavel=''){ const wrap = document.getElementById(listId); if(!wrap) return; const div = document.createElement('div'); div.className = 'v8d-check-item' + (checked?' done':''); div.innerHTML = `
`; wrap.appendChild(div); const inp = div.querySelector('input[type=text]'); if(!text) inp.focus(); } function v8dToggleAnexo(key, val){ const sim = document.getElementById('v8dSim'+key); const nao = document.getElementById('v8dNao'+key); if(!sim||!nao) return; const current = sim.dataset.sel==='sim'?'sim': nao.dataset.sel==='nao'?'nao':''; sim.classList.remove('active'); nao.classList.remove('active'); sim.dataset.sel=''; nao.dataset.sel=''; if(current !== val){ if(val==='sim'){ sim.classList.add('active'); sim.dataset.sel='sim'; } else { nao.classList.add('active'); nao.dataset.sel='nao'; } } } function v8dLoad(data){ V8D_LISTS.forEach(id=>{ const wrap = document.getElementById(id); if(!wrap) return; wrap.innerHTML=''; (data[id]||[]).forEach(it=>v8dAddCheck(id, it.text, it.checked, it.status, it.data||'', it.responsavel||'')); }); const refIds = ['v8dRefsD3qc','v8dRefsD3proc','v8dRefsD56','v8dRefsD78']; const refKeys = ['refsD3qc','refsD3proc','refsD56','refsD78']; refIds.forEach((id,i)=>{ const wrap = document.getElementById(id); if(!wrap) return; wrap.innerHTML=''; (data[refKeys[i]]||[]).forEach(r=>v8dAddRef(id, r.text, r.status, r.data||'', r.responsavel||'')); }); } function v8dCollect(){ const data={}; V8D_LISTS.forEach(id=>{ const wrap=document.getElementById(id); if(!wrap){data[id]=[];return;} data[id]=Array.from(wrap.querySelectorAll('.v8d-check-item')).map(div=>{ const inputs = div.querySelectorAll('input[type=text]'); return { text: inputs[0]?.value.trim()||'', responsavel: inputs[1]?.value.trim()||'', data: div.querySelector('input[type=date]')?.value||'', checked: false, status: div.querySelector('.v8d-ref-sim')?.classList.contains('active')?'sim': div.querySelector('.v8d-ref-nao')?.classList.contains('active')?'nao':'' }; }).filter(it=>it.text); }); const refIds = ['v8dRefsD3qc','v8dRefsD3proc','v8dRefsD56','v8dRefsD78']; const refKeys = ['refsD3qc','refsD3proc','refsD56','refsD78']; refIds.forEach((id,i)=>{ const wrap=document.getElementById(id); if(!wrap){data[refKeys[i]]=[];return;} data[refKeys[i]]=Array.from(wrap.querySelectorAll('.v8d-ref-item')).map(div=>{ const inputs = div.querySelectorAll('input[type=text]'); return { text: inputs[0]?.value.trim()||'', responsavel: inputs[1]?.value.trim()||'', data: div.querySelector('input[type=date]')?.value||'', status: div.querySelector('.v8d-ref-sim')?.classList.contains('active')?'sim': div.querySelector('.v8d-ref-nao')?.classList.contains('active')?'nao':'' }; }).filter(r=>r.text); }); return data; } async function salvarV8d(){ if(!verifIid) return; const issue = issues.find(i=>i.internalId===verifIid); if(!issue) return; issue.etapas8d = v8dCollect(); await saveIssue(issue); showToast('✓ Etapas 8D salvas!'); } // ====================== ETAPA LINHAS ====================== function addEtapaLinha(texto=''){ const wrap = document.getElementById('etapaListWrap'); if(!wrap) return; const div = document.createElement('div'); div.className = 'etapa-list-item'; div.innerHTML = ` `; wrap.appendChild(div); const inp = div.querySelector('input'); if(!texto) inp.focus(); inp.addEventListener('keydown', e=>{ if(e.key === 'Enter'){ e.preventDefault(); addEtapaLinha(); } }); } function loadEtapaLinhas(linhas){ const wrap = document.getElementById('etapaListWrap'); if(!wrap) return; wrap.innerHTML = ''; if(!linhas || !linhas.length){ addEtapaLinha(); return; } linhas.forEach(l => addEtapaLinha(l)); } function collectEtapaLinhas(){ const wrap = document.getElementById('etapaListWrap'); if(!wrap) return []; return Array.from(wrap.querySelectorAll('input[type=text]')) .map(i=>i.value.trim()).filter(v=>v); } // ====================== FILTROS AVANÇADOS ====================== function toggleAdvFilters(){ const el = document.getElementById('filtersAdvanced'); const btn = document.getElementById('btnAdvFilters'); const open = el.classList.toggle('open'); btn.textContent = open ? 'Filtros avançados ▴' : 'Filtros avançados ▾'; } function limparFiltrosAvancados(){ ['fltMarca','fltModelo','fltSetor','fltTurno','fltResp'].forEach(id=>{ const el = document.getElementById(id); if(el) el.value = ''; }); render(); } // ====================== TEMA ====================== function toggleTema(){ const root = document.documentElement; const btn = document.getElementById('btnTema'); if(root.classList.contains('tema-claro')){ root.classList.remove('tema-claro'); localStorage.setItem('fic-tema','escuro'); if(btn) btn.textContent = '☀️ Tema Claro'; } else { root.classList.add('tema-claro'); localStorage.setItem('fic-tema','claro'); if(btn) btn.textContent = '🌙 Tema Escuro'; } } function carregarTema(){ const tema = localStorage.getItem('fic-tema'); const btn = document.getElementById('btnTema'); if(tema === 'claro'){ document.documentElement.classList.add('tema-claro'); if(btn) btn.textContent = '🌙 Tema Escuro'; } } // ====================== MERGE CONFIG ====================== function mergeCfg(saved){ const base = JSON.parse(JSON.stringify(DEFAULT_CFG)); if(!saved) return base; return { gradeDefinitions: saved.gradeDefinitions || base.gradeDefinitions, statuses: saved.statuses || base.statuses, marcas: saved.marcas || base.marcas, modelos: saved.modelos || base.modelos, setores: saved.setores || base.setores, levels: saved.levels || base.levels }; } async function salvarCfgManual(){ await saveConfig(); populateSelects(); populateFilterOptions(); const msg = document.getElementById('cfgSaveMsg'); if(msg){ msg.textContent = '✓ Salvo com sucesso!'; msg.style.opacity='1'; setTimeout(()=>msg.style.opacity='0', 2500); } } // ====================== CONFIGURAÇÕES ====================== let cfgActiveTab='setor'; function openCfg(){ document.body.classList.add('modal-open'); cfgActiveTab='setor'; document.querySelectorAll('.cfg-tab').forEach((t,i)=>t.classList.toggle('active',i===0)); document.querySelectorAll('.cfg-panel').forEach((p,i)=>p.classList.toggle('active',i===0)); ['setor','marca','modelo','nivel','grade','status'].forEach(k=>{ renderCfgList(k); const inp=document.getElementById('cfgInput-'+k); if(inp){ inp.onkeydown=e=>{ if(e.key==='Enter'){if(k==='grade') cfgAddGrade(); else cfgAdd(k);} }; } }); document.getElementById('cfgOverlay').classList.add('open'); } function closeCfg(){ document.getElementById('cfgOverlay').classList.remove('open'); document.body.classList.remove('modal-open'); populateSelects(); populateFilterOptions(); } function cfgTab(key,btn){ cfgActiveTab=key; document.querySelectorAll('.cfg-tab').forEach(t=>t.classList.remove('active')); btn.classList.add('active'); document.querySelectorAll('.cfg-panel').forEach(p=>p.classList.remove('active')); document.getElementById('cfgPanel-'+key).classList.add('active'); renderCfgList(key); } function cfgGetList(key){ if(key==='setor') return cfg.setores||[]; if(key==='marca') return cfg.marcas||[]; if(key==='modelo') return cfg.modelos||[]; if(key==='nivel') return cfg.levels||[]; if(key==='grade') return cfg.gradeDefinitions||[]; if(key==='status') return cfg.statuses||[]; return []; } function renderCfgList(key){ const el=document.getElementById('cfgList-'+key); if(!el) return; const list=cfgGetList(key); if(!list.length){ el.innerHTML=`
Nenhum item cadastrado.
`; return; } if(key==='grade'){ el.innerHTML=list.map((g,i)=>`
${esc(g.name)}
`).join(''); } else if(key==='status'){ el.innerHTML=list.map((s,i)=>`
${esc(s.nome)} (${s.limiteHoras}h)
`).join(''); } else { el.innerHTML=list.map((item,i)=>`
${esc(item)}
`).join(''); } } async function cfgAdd(key){ const inp=document.getElementById('cfgInput-'+key); if(!inp) return; const val=inp.value.trim(); if(!val) return; if(key==='setor') { if(!cfg.setores) cfg.setores=[]; cfg.setores.push(val); } if(key==='marca') { if(!cfg.marcas) cfg.marcas=[]; cfg.marcas.push(val); } if(key==='modelo') { if(!cfg.modelos) cfg.modelos=[]; cfg.modelos.push(val); } if(key==='nivel') { if(!cfg.levels) cfg.levels=[]; cfg.levels.push(val); } if(key==='status'){ const h=parseInt(document.getElementById('cfgInput-statusHoras')?.value)||48; if(!cfg.statuses) cfg.statuses=[]; cfg.statuses.push({id:'s'+Date.now(),nome:val,limiteHoras:h}); const hi=document.getElementById('cfgInput-statusHoras'); if(hi) hi.value=''; } inp.value=''; await saveConfig(); renderCfgList(key); populateSelects(); } async function cfgAddGrade(){ const inp=document.getElementById('cfgInput-grade'); const col=document.getElementById('cfgInput-gradeColor'); const val=inp?.value.trim(); if(!val) return; if(!cfg.gradeDefinitions) cfg.gradeDefinitions=[]; cfg.gradeDefinitions.push({name:val, color:col?.value||'#3b82f6'}); inp.value=''; await saveConfig(); renderCfgList('grade'); populateSelects(); } async function cfgDel(key,idx){ if(key==='setor') cfg.setores.splice(idx,1); else if(key==='marca') cfg.marcas.splice(idx,1); else if(key==='modelo') cfg.modelos.splice(idx,1); else if(key==='nivel') cfg.levels.splice(idx,1); else if(key==='grade') cfg.gradeDefinitions.splice(idx,1); else if(key==='status') cfg.statuses.splice(idx,1); await saveConfig(); renderCfgList(key); populateSelects(); } function pickColor(idx){ const inp=document.createElement('input'); inp.type='color'; inp.value=cfg.gradeDefinitions[idx].color; inp.oninput=async e=>{ cfg.gradeDefinitions[idx].color=e.target.value; await saveConfig(); renderCfgList('grade'); }; inp.click(); } // ====================== INIT ====================== window.addEventListener('DOMContentLoaded', async ()=>{ document.getElementById('loginEmail').addEventListener('keydown', e=>{ if(e.key==='Enter') document.getElementById('loginPassword').focus(); }); document.getElementById('loginPassword').addEventListener('keydown', e=>{ if(e.key==='Enter') doLogin(); }); document.getElementById('loadingScreen').classList.add('show'); const { data: { session } } = await sb.auth.getSession(); if(session && session.user){ currentUser = session.user; document.getElementById('loginScreen').classList.remove('show'); await iniciarApp(); } else { document.getElementById('loadingScreen').classList.remove('show'); document.getElementById('loginScreen').classList.add('show'); } sb.auth.onAuthStateChange(async (event, session) => { if(event === 'SIGNED_IN' && session && session.user && !currentUser){ currentUser = session.user; document.getElementById('loginScreen').classList.remove('show'); await iniciarApp(); } if(event === 'SIGNED_OUT'){ currentUser = null; } }); });