Adiciona icones de Envio e Lixeira para assembleias com suporte a exclusao
This commit is contained in:
@@ -83,7 +83,7 @@ public final class ClienteHandlers implements HttpHandler {
|
||||
if(p.length==3&&"condominios".equals(p[0])&&"espacos-comuns".equals(p[2])){ long cond=id(p[1]); if(!podeAcessarCondominio(c,cargo,funcionarioId,cond)){HttpResponses.json(ex,403,Map.of("erro","condominio_nao_vinculado"));return;} if("POST".equals(method)) criarEspaco(ex,c,cond,funcionarioId); else if("GET".equals(method)) listarParam(ex,c,"SELECT * FROM espacos_comuns WHERE condominio_id=? ORDER BY nome",cond,"espacos"); else HttpResponses.methodNotAllowed(ex); return; }
|
||||
if(p.length==4&&"condominios".equals(p[0])&&"espacos-comuns".equals(p[2])&&"PUT".equals(method)){ long cond=id(p[1]); if(!podeAcessarCondominio(c,cargo,funcionarioId,cond)){HttpResponses.json(ex,403,Map.of("erro","condominio_nao_vinculado"));return;} atualizarEspaco(ex,c,cond,id(p[3]),funcionarioId); return; }
|
||||
if(p.length==3&&"condominios".equals(p[0])&&"assembleias".equals(p[2])){ long cond=id(p[1]); if(!podeAcessarCondominio(c,cargo,funcionarioId,cond)){HttpResponses.json(ex,403,Map.of("erro","condominio_nao_vinculado"));return;} if("POST".equals(method)) criarAssembleia(ex,c,empresaId,cond,funcionarioId); else if("GET".equals(method)) listarParam(ex,c,"SELECT * FROM assembleias WHERE condominio_id=? ORDER BY data_hora DESC",cond,"assembleias"); else HttpResponses.methodNotAllowed(ex); return; }
|
||||
if(p.length==4&&"condominios".equals(p[0])&&"assembleias".equals(p[2])&&"PUT".equals(method)){ long cond=id(p[1]); if(!podeAcessarCondominio(c,cargo,funcionarioId,cond)){HttpResponses.json(ex,403,Map.of("erro","condominio_nao_vinculado"));return;} atualizarAssembleia(ex,c,empresaId,cond,id(p[3]),funcionarioId); return; }
|
||||
if(p.length==4&&"condominios".equals(p[0])&&"assembleias".equals(p[2])){ long cond=id(p[1]); if(!podeAcessarCondominio(c,cargo,funcionarioId,cond)){HttpResponses.json(ex,403,Map.of("erro","condominio_nao_vinculado"));return;} if("PUT".equals(method)) atualizarAssembleia(ex,c,empresaId,cond,id(p[3]),funcionarioId); else if("DELETE".equals(method)) excluirAssembleia(ex,c,empresaId,cond,id(p[3]),funcionarioId); else HttpResponses.methodNotAllowed(ex); return; }
|
||||
if(p.length==5&&"condominios".equals(p[0])&&"assembleias".equals(p[2])&&"notificar".equals(p[4])&&"POST".equals(method)){ long cond=id(p[1]); notificarAssembleia(ex,c,empresaId,cond,id(p[3]),funcionarioId); return; }
|
||||
if(p.length==3&&"condominios".equals(p[0])&&"documentos".equals(p[2])){ long cond=id(p[1]); if(!podeAcessarCondominio(c,cargo,funcionarioId,cond)){HttpResponses.json(ex,403,Map.of("erro","condominio_nao_vinculado"));return;} if("POST".equals(method)) uploadDocumento(ex,c,empresaId,cond,funcionarioId); else if("GET".equals(method)) listarParam(ex,c,"SELECT * FROM documentos WHERE condominio_id=? ORDER BY criado_em DESC",cond,"documentos"); else HttpResponses.methodNotAllowed(ex); return; }
|
||||
if(p.length==3&&"documentos".equals(p[0])&&"download".equals(p[2])&&"GET".equals(method)){ downloadDocumento(ex,c,id(p[1])); return; }
|
||||
@@ -257,6 +257,38 @@ public final class ClienteHandlers implements HttpHandler {
|
||||
HttpResponses.json(ex,200,Map.of("ok",true,"status_envio",st,"mensagem","Notificação enviada com sucesso!"));
|
||||
}
|
||||
}
|
||||
private void excluirAssembleia(HttpExchange ex,Connection c,long emp,long cond,long aid,long fid)throws Exception{
|
||||
Map<String,Object> old=one(c,"SELECT * FROM assembleias WHERE id=? AND condominio_id=?",Arrays.asList(aid,cond));
|
||||
if(old==null){
|
||||
HttpResponses.json(ex,404,Map.of("erro","assembleia_nao_encontrada","mensagem","Assembleia não encontrada."));
|
||||
return;
|
||||
}
|
||||
List<Map<String,Object>> avisos=rows(c,"SELECT id FROM avisos WHERE assembleia_id=?",Arrays.asList(aid));
|
||||
c.setAutoCommit(false);
|
||||
try{
|
||||
for(Map<String,Object> av:avisos){
|
||||
long avisoId=((Number)av.get("id")).longValue();
|
||||
try(PreparedStatement ps=c.prepareStatement("DELETE FROM aviso_documentos WHERE aviso_id=?")){ps.setLong(1,avisoId);ps.executeUpdate();}
|
||||
try(PreparedStatement ps=c.prepareStatement("DELETE FROM aviso_destinatarios WHERE aviso_id=?")){ps.setLong(1,avisoId);ps.executeUpdate();}
|
||||
try(PreparedStatement ps=c.prepareStatement("DELETE FROM fila_envio WHERE tipo='aviso' AND referencia_id=?")){ps.setLong(1,avisoId);ps.executeUpdate();}
|
||||
try(PreparedStatement ps=c.prepareStatement("DELETE FROM avisos WHERE id=?")){ps.setLong(1,avisoId);ps.executeUpdate();}
|
||||
try(Connection m=masterDs.getMasterConnection();PreparedStatement ps=m.prepareStatement("DELETE FROM logs_envio_avisos WHERE empresa_id=? AND condominio_id=? AND aviso_id=?")){ps.setLong(1,emp);ps.setLong(2,cond);ps.setLong(3,avisoId);ps.executeUpdate();}
|
||||
}
|
||||
try(PreparedStatement ps=c.prepareStatement("DELETE FROM assembleias WHERE id=? AND condominio_id=?")){
|
||||
ps.setLong(1,aid);
|
||||
ps.setLong(2,cond);
|
||||
ps.executeUpdate();
|
||||
}
|
||||
audit(c,fid,"delete","assembleias",aid,old,Map.of("ok",true));
|
||||
c.commit();
|
||||
HttpResponses.json(ex,200,Map.of("ok",true,"mensagem","Assembleia excluída com sucesso."));
|
||||
}catch(Exception err){
|
||||
c.rollback();
|
||||
throw err;
|
||||
}finally{
|
||||
c.setAutoCommit(true);
|
||||
}
|
||||
}
|
||||
private void uploadDocumento(HttpExchange ex,Connection c,long emp,long cond,long fid)throws Exception{Multipart mp=parseMultipart(ex); if(mp.bytes.length>MAX_UPLOAD){HttpResponses.json(ex,400,Map.of("erro","arquivo_muito_grande"));return;} String ext=ext(mp.filename); if(!EXT_OK.contains(ext)){HttpResponses.json(ex,400,Map.of("erro","extensao_nao_permitida"));return;} String db=databaseName(emp); Path dir=uploadRoot.resolve(db).resolve(String.valueOf(cond)); Files.createDirectories(dir); String safe=UUID.randomUUID()+"-"+mp.filename.replaceAll("[^a-zA-Z0-9._-]","_"); Path file=dir.resolve(safe); Files.write(file,mp.bytes); String rel=db+"/"+cond+"/"+safe; long id=insert(c,"INSERT INTO documentos (condominio_id,tipo,nome_arquivo,caminho_armazenamento,enviado_por) VALUES (?,?,?,?,?)",Arrays.asList(cond,nullable(mp.tipo),mp.filename,rel,fid)); audit(c,fid,"create","documentos",id,null,Map.of("nome_arquivo",mp.filename)); HttpResponses.json(ex,201,Map.of("documento",one(c,"SELECT * FROM documentos WHERE id=?",Arrays.asList(id))));}
|
||||
private void downloadDocumento(HttpExchange ex,Connection c,long id)throws Exception{Map<String,Object>d=one(c,"SELECT * FROM documentos WHERE id=?",Arrays.asList(id)); if(d==null){HttpResponses.json(ex,404,Map.of("erro","documento_nao_encontrado"));return;} Path f=uploadRoot.resolve(String.valueOf(d.get("caminho_armazenamento"))); if(!Files.exists(f)){HttpResponses.json(ex,404,Map.of("erro","arquivo_nao_encontrado"));return;} ex.getResponseHeaders().set("Content-Disposition","attachment; filename=\""+d.get("nome_arquivo")+"\""); ex.sendResponseHeaders(200,Files.size(f)); Files.copy(f,ex.getResponseBody()); ex.close();}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ function formHtml(r={}){
|
||||
function renderAssembleias(){
|
||||
const q=termo();
|
||||
const lista=assembleias.filter(a=>contem(q,a.condominio_nome,a.tipo,a.data_hora,a.local,a.status,destinatariosLabel(a)));
|
||||
rows.innerHTML=lista.map(a=>`<tr><td><strong>${esc(a.condominio_nome||'-')}</strong></td><td>${esc(a.tipo)}</td><td>${Util.date(a.data_hora)}</td><td>${esc(a.local||'')}</td><td>${Util.badge(a.status)}</td><td>${esc(destinatariosLabel(a))}</td><td><button class="btn secondary" type="button" onclick="enviarNotificacaoAssembleia(this,${a.condominio_id},${a.id})">Enviar notificação</button></td></tr>`).join('')||'<tr><td colspan="7">Nenhuma assembleia encontrada.</td></tr>';
|
||||
rows.innerHTML=lista.map(a=>`<tr><td><strong>${esc(a.condominio_nome||'-')}</strong></td><td>${esc(a.tipo)}</td><td>${Util.date(a.data_hora)}</td><td>${esc(a.local||'')}</td><td>${Util.badge(a.status)}</td><td>${esc(destinatariosLabel(a))}</td><td><div class="table-actions"><button class="table-icon-btn send" type="button" onclick="enviarNotificacaoAssembleia(this,${a.condominio_id},${a.id})" title="Enviar notificação" aria-label="Enviar notificação"><svg viewBox="0 0 24 24" aria-hidden="true"><line x1="22" y1="2" x2="11" y2="13"></line><polygon points="22 2 15 22 11 13 2 9 22 2"></polygon></svg></button><button class="table-icon-btn danger" type="button" onclick="excluirAssembleia(${a.condominio_id},${a.id})" title="Excluir assembleia" aria-label="Excluir assembleia"><svg viewBox="0 0 24 24" aria-hidden="true"><polyline points="3 6 5 6 21 6"></polyline><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path><line x1="10" y1="11" x2="10" y2="17"></line><line x1="14" y1="11" x2="14" y2="17"></line></svg></button></div></td></tr>`).join('')||'<tr><td colspan="7">Nenhuma assembleia encontrada.</td></tr>';
|
||||
}
|
||||
function ensureCalendarModal(){let m=document.querySelector('#assembleia-calendar-modal');if(m)return m;document.body.insertAdjacentHTML('beforeend','<div id="assembleia-calendar-modal" class="modal hidden"><div class="modal-backdrop" onclick="fecharCalendarioAssembleias()"></div><section class="modal-panel calendar-modal"><div class="modal-head"><h2>Calendário de assembleias</h2><button class="btn secondary" type="button" onclick="fecharCalendarioAssembleias()">Fechar</button></div><div class="calendar-layout"><div><div class="calendar-toolbar"><button class="btn secondary" type="button" onclick="mudarMesCalendario(-1)">Anterior</button><strong id="calendar-title"></strong><button class="btn secondary" type="button" onclick="mudarMesCalendario(1)">Próximo</button></div><div id="calendar-grid" class="calendar-grid"></div></div><aside class="calendar-side"><h3 id="calendar-day-title">Selecione um dia</h3><div id="calendar-day-list" class="calendar-day-list"><p class="muted">Clique em um dia para ver as assembleias.</p></div></aside></div></section></div>');return document.querySelector('#assembleia-calendar-modal')}
|
||||
function renderCalendarioAssembleias(selected){ensureCalendarModal();const title=document.querySelector('#calendar-title'),grid=document.querySelector('#calendar-grid');title.textContent=monthLabel(calMonth);const y=calMonth.getFullYear(),m=calMonth.getMonth(),start=new Date(y,m,1-new Date(y,m,1).getDay()),todayKey=dateKey(new Date());let html=['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'].map(x=>'<div class="calendar-weekday">'+x+'</div>').join('');for(let i=0;i<42;i++){const d=new Date(start);d.setDate(start.getDate()+i);const key=dateKey(d),items=assembleias.filter(a=>dateKey(a.data_hora)===key),classes=['calendar-day'];if(d.getMonth()!==m)classes.push('other');if(items.length)classes.push('busy');if(key===todayKey)classes.push('today');html+='<button type="button" class="'+classes.join(' ')+'" data-date="'+key+'"><span>'+d.getDate()+'</span>'+(items.length?'<b>'+items.length+'</b>':'')+'</button>'}grid.innerHTML=html;grid.querySelectorAll('.calendar-day').forEach(btn=>btn.onclick=()=>selecionarDiaCalendario(btn.dataset.date));if(selected)selecionarDiaCalendario(selected,false)}
|
||||
@@ -68,8 +68,9 @@ window.alternarBuscaAssembleias=()=>{
|
||||
window.abrirCalendarioAssembleias=async()=>{try{if(!assembleias.length)await load();calMonth=new Date();ensureCalendarModal().classList.remove('hidden');renderCalendarioAssembleias()}catch(e){Util.toast(e.message,true)}};
|
||||
window.fecharCalendarioAssembleias=()=>document.querySelector('#assembleia-calendar-modal')?.classList.add('hidden');
|
||||
window.mudarMesCalendario=delta=>{calMonth=new Date(calMonth.getFullYear(),calMonth.getMonth()+delta,1);renderCalendarioAssembleias()};
|
||||
window.selecionarDiaCalendario=(key,mark=true)=>{if(mark)document.querySelectorAll('.calendar-day').forEach(x=>x.classList.toggle('selected',x.dataset.date===key));const list=document.querySelector('#calendar-day-list'),title=document.querySelector('#calendar-day-title'),items=assembleias.filter(a=>dateKey(a.data_hora)===key);const [yy,mm,dd]=key.split('-');title.textContent=dd+'/'+mm+'/'+yy;if(!items.length){list.innerHTML='<p class="muted">Nenhuma assembleia agendada neste dia.</p>';return;}list.innerHTML=items.map(a=>'<div class="calendar-event"><strong>'+esc(a.condominio_nome||'-')+'</strong><span>'+Util.date(a.data_hora)+'</span><span>'+esc(a.tipo)+' - '+esc(a.local||'-')+'</span><p>'+esc(destinatariosLabel(a))+'</p><button class="btn secondary" type="button" onclick="enviarNotificacaoAssembleia(this,'+a.condominio_id+','+a.id+')">Enviar notificação</button></div>').join('')};
|
||||
window.enviarNotificacaoAssembleia=async(btn,condominioId,assembleiaId)=>{if(!await Util.confirm('Deseja enviar a notificação para os contatos e responsáveis desta assembleia?','Enviar notificação'))return;const original=btn?btn.textContent:'';if(btn){btn.disabled=true;btn.textContent='Enviando...';}try{const res=await Api.post(`/api/condominios/${condominioId}/assembleias/${assembleiaId}/notificar`,{});if(res&&res.ok===false){Util.toast(res.mensagem||'Falha ao enviar notificação.',true);}else{Util.toast(res?.mensagem||'Notificação enviada com sucesso!');}await load();}catch(err){Util.toast(err.message,true);}finally{if(btn){btn.disabled=false;btn.textContent=original;}}};
|
||||
window.selecionarDiaCalendario=(key,mark=true)=>{if(mark)document.querySelectorAll('.calendar-day').forEach(x=>x.classList.toggle('selected',x.dataset.date===key));const list=document.querySelector('#calendar-day-list'),title=document.querySelector('#calendar-day-title'),items=assembleias.filter(a=>dateKey(a.data_hora)===key);const [yy,mm,dd]=key.split('-');title.textContent=dd+'/'+mm+'/'+yy;if(!items.length){list.innerHTML='<p class="muted">Nenhuma assembleia agendada neste dia.</p>';return;}list.innerHTML=items.map(a=>'<div class="calendar-event"><strong>'+esc(a.condominio_nome||'-')+'</strong><span>'+Util.date(a.data_hora)+'</span><span>'+esc(a.tipo)+' - '+esc(a.local||'-')+'</span><p>'+esc(destinatariosLabel(a))+'</p><div class="row compact"><button class="btn secondary" type="button" onclick="enviarNotificacaoAssembleia(this,'+a.condominio_id+','+a.id+')">Enviar notificação</button><button class="btn danger" type="button" onclick="excluirAssembleia('+a.condominio_id+','+a.id+')">Excluir</button></div></div>').join('')};
|
||||
window.enviarNotificacaoAssembleia=async(btn,condominioId,assembleiaId)=>{if(!await Util.confirm('Deseja enviar a notificação para os contatos e responsáveis desta assembleia?','Enviar notificação'))return;const original=btn?btn.textContent:'';if(btn){btn.disabled=true;btn.textContent='...';}try{const res=await Api.post(`/api/condominios/${condominioId}/assembleias/${assembleiaId}/notificar`,{});if(res&&res.ok===false){Util.toast(res.mensagem||'Falha ao enviar notificação.',true);}else{Util.toast(res?.mensagem||'Notificação enviada com sucesso!');}await load();}catch(err){Util.toast(err.message,true);}finally{if(btn){btn.disabled=false;btn.textContent=original;}}};
|
||||
window.excluirAssembleia=async(condominioId,assembleiaId)=>{if(!await Util.confirm('Tem certeza que deseja excluir esta assembleia? Esta ação não pode ser desfeita.','Excluir assembleia'))return;try{const res=await Api.request(`/api/condominios/${condominioId}/assembleias/${assembleiaId}`,{method:'DELETE'});Util.toast(res?.mensagem||'Assembleia excluída com sucesso.');await load();if(document.querySelector('#assembleia-calendar-modal')&&!document.querySelector('#assembleia-calendar-modal').classList.contains('hidden')){renderCalendarioAssembleias();}}catch(err){Util.toast(err.message,true);}};
|
||||
window.abrirNovoResponsavel=()=>abrirResponsavel({});
|
||||
window.editarResponsavel=id=>{const r=responsaveis.find(x=>Number(x.id)===Number(id));if(r)abrirResponsavel(r)};
|
||||
window.fecharResponsavelModal=()=>{modal.classList.add('hidden');modalBody.innerHTML=''};
|
||||
|
||||
@@ -37,7 +37,8 @@ function renderEspacos(){const q=termoDetalhe('espacos');const lista=espacos.fil
|
||||
window.abrirNovoEspaco=()=>{abrirDetailModal('Novo espaco comum','<form id="espaco-form" class="grid cols"><div class="field"><label>Nome</label><input name="nome" required></div><div class="field"><label>Valor centavos</label><input name="valor_utilizacao_centavos" type="number"></div><div class="field"><label>Indice</label><input name="indice_correcao"></div><div class="field"><label>Descricao</label><input name="descricao"></div><div class="row"><button class="btn">Cadastrar</button><button class="btn secondary" type="button" onclick="fecharDetailModal()">Cancelar</button></div></form>');document.querySelector('#espaco-form').onsubmit=async e=>{e.preventDefault();try{await Api.post(`/api/condominios/${id}/espacos-comuns`,Util.formData(e.target));Util.toast('Espaco salvo');fecharDetailModal();loadEspacos()}catch(err){Util.toast(err.message,true)}}};
|
||||
|
||||
async function loadAssembleias(){const d=await Api.get(`/api/condominios/${id}/assembleias`);assembleias=d.assembleias||[];renderAssembleias()}
|
||||
function renderAssembleias(){const q=termoDetalhe('assembleias');const lista=assembleias.filter(a=>contemDetalhe(q,a.tipo,a.data_hora,a.local,a.status));const calendar='<button class="icon-btn calendar-open" type="button" onclick="abrirCalendarioAssembleias()" title="Calendário de assembleias" aria-label="Calendário de assembleias"></button>';document.querySelector('#assembleias').innerHTML=headerCadastro('Assembleias','assembleias','abrirNovaAssembleia()',calendar)+`<div class="table-wrap"><table><thead><tr><th>Tipo</th><th>Data</th><th>Local</th><th>Status</th></tr></thead><tbody>${lista.map(a=>`<tr><td>${esc(a.tipo)}</td><td>${Util.date(a.data_hora)}</td><td>${esc(a.local||'')}</td><td>${Util.badge(a.status)}</td></tr>`).join('')||'<tr><td colspan="4">Nenhuma assembleia encontrada.</td></tr>'}</tbody></table></div>`;document.querySelector('#assembleias-search-input')?.addEventListener('input',renderAssembleias)}
|
||||
function renderAssembleias(){const q=termoDetalhe('assembleias');const lista=assembleias.filter(a=>contemDetalhe(q,a.tipo,a.data_hora,a.local,a.status));const calendar='<button class="icon-btn calendar-open" type="button" onclick="abrirCalendarioAssembleias()" title="Calendário de assembleias" aria-label="Calendário de assembleias"></button>';document.querySelector('#assembleias').innerHTML=headerCadastro('Assembleias','assembleias','abrirNovaAssembleia()',calendar)+`<div class="table-wrap"><table><thead><tr><th>Tipo</th><th>Data</th><th>Local</th><th>Status</th><th>Ações</th></tr></thead><tbody>${lista.map(a=>`<tr><td>${esc(a.tipo)}</td><td>${Util.date(a.data_hora)}</td><td>${esc(a.local||'')}</td><td>${Util.badge(a.status)}</td><td><div class="table-actions"><button class="table-icon-btn send" type="button" onclick="reenviarAvisoAssembleia(${id},${a.id})" title="Enviar notificação" aria-label="Enviar notificação"><svg viewBox="0 0 24 24" aria-hidden="true"><line x1="22" y1="2" x2="11" y2="13"></line><polygon points="22 2 15 22 11 13 2 9 22 2"></polygon></svg></button><button class="table-icon-btn danger" type="button" onclick="excluirAssembleiaDetalhe(${a.id})" title="Excluir assembleia" aria-label="Excluir assembleia"><svg viewBox="0 0 24 24" aria-hidden="true"><polyline points="3 6 5 6 21 6"></polyline><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path><line x1="10" y1="11" x2="10" y2="17"></line><line x1="14" y1="11" x2="14" y2="17"></line></svg></button></div></td></tr>`).join('')||'<tr><td colspan="5">Nenhuma assembleia encontrada.</td></tr>'}</tbody></table></div>`;document.querySelector('#assembleias-search-input')?.addEventListener('input',renderAssembleias)}
|
||||
window.excluirAssembleiaDetalhe=async aid=>{if(!await Util.confirm('Tem certeza que deseja excluir esta assembleia? Esta ação não pode ser desfeita.','Excluir assembleia'))return;try{await Api.request(`/api/condominios/${id}/assembleias/${aid}`,{method:'DELETE'});Util.toast('Assembleia excluída');await loadAssembleias();await load();}catch(err){Util.toast(err.message,true);}};
|
||||
window.abrirNovaAssembleia=()=>{abrirDetailModal('Nova assembleia','<form id="ass-form" class="grid cols"><div class="field"><label>Tipo</label><input name="tipo" required></div><div class="field"><label>Data e hora</label><input name="data_hora" type="datetime-local" required></div><div class="field"><label>Local</label><input name="local"></div><div class="field"><label>Pauta</label><input name="pauta"></div><div class="row"><button class="btn">Cadastrar</button><button class="btn secondary" type="button" onclick="fecharDetailModal()">Cancelar</button></div></form>');document.querySelector('#ass-form').onsubmit=async e=>{e.preventDefault();try{await Api.post(`/api/condominios/${id}/assembleias`,Util.formData(e.target));Util.toast('Assembleia salva');fecharDetailModal();loadAssembleias();load()}catch(err){Util.toast(err.message,true)}}};
|
||||
async function loadFuncionariosVinculados(){const d=await Api.get(`/api/condominios/${id}/funcionarios-vinculados`);funcionariosVinculados=d.funcionarios||[]}
|
||||
async function loadExtras(){const d=await Api.get(`/api/extras`);extras=(d.extras||[]).filter(x=>x.status==='ativo')}
|
||||
|
||||
@@ -486,6 +486,71 @@ td .btn,
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.table-actions {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.table-icon-btn {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: var(--radius-sm);
|
||||
background: #ffffff;
|
||||
color: var(--muted-strong);
|
||||
cursor: pointer;
|
||||
display: inline-grid;
|
||||
place-items: center;
|
||||
padding: 0;
|
||||
box-shadow: none;
|
||||
transition: all .16s ease;
|
||||
}
|
||||
|
||||
.table-icon-btn:hover {
|
||||
background: var(--bg-soft);
|
||||
color: var(--brand);
|
||||
border-color: var(--brand);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.table-icon-btn.send {
|
||||
color: var(--brand);
|
||||
}
|
||||
|
||||
.table-icon-btn.send:hover {
|
||||
background: var(--brand-soft);
|
||||
border-color: var(--brand);
|
||||
color: var(--brand-strong);
|
||||
}
|
||||
|
||||
.table-icon-btn.danger {
|
||||
color: var(--danger);
|
||||
}
|
||||
|
||||
.table-icon-btn.danger:hover {
|
||||
background: var(--danger-soft);
|
||||
border-color: var(--danger);
|
||||
color: var(--danger);
|
||||
}
|
||||
|
||||
.table-icon-btn svg {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
fill: none;
|
||||
stroke: currentColor;
|
||||
stroke-width: 2;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
}
|
||||
|
||||
.table-icon-btn:disabled {
|
||||
opacity: .5;
|
||||
cursor: not-allowed;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
tbody tr:hover {
|
||||
background: #f8fbfc;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user