feat: add setores display and loading state to perfil page, and implement click outside functionality for dropdown menus in funcionarios page
This commit is contained in:
@@ -199,6 +199,13 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const setoresQuery = $derived.by(() => {
|
||||||
|
if (!funcionarioIdParaQueries) return { data: [] };
|
||||||
|
return useQuery(api.setores.getSetoresByFuncionario, {
|
||||||
|
funcionarioId: funcionarioIdParaQueries
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
if (meuTimeQuery?.data && funcionarioIdParaQueries) {
|
if (meuTimeQuery?.data && funcionarioIdParaQueries) {
|
||||||
meuTimeEstavel = meuTimeQuery.data;
|
meuTimeEstavel = meuTimeQuery.data;
|
||||||
@@ -1186,6 +1193,41 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="hover:bg-base-200/60 border-base-300/50 flex items-start gap-3 rounded-lg border p-4 shadow-sm transition-all hover:shadow-md"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="flex h-10 w-10 items-center justify-center rounded-lg bg-gradient-to-br from-teal-500/20 to-teal-600/20"
|
||||||
|
>
|
||||||
|
<ListChecks class="h-5 w-5 text-teal-600" strokeWidth={2} />
|
||||||
|
</div>
|
||||||
|
<div class="flex-1">
|
||||||
|
<span
|
||||||
|
class="label-text text-base-content/60 text-xs font-semibold tracking-wide uppercase"
|
||||||
|
>Setores</span
|
||||||
|
>
|
||||||
|
{#if setoresQuery?.data && setoresQuery.data.length > 0}
|
||||||
|
<div class="mt-2 flex flex-wrap gap-2">
|
||||||
|
{#each setoresQuery.data as setor}
|
||||||
|
<div
|
||||||
|
class="badge badge-lg font-semibold shadow-sm"
|
||||||
|
style="background-color: rgba(20, 184, 166, 0.1); border-color: rgba(20, 184, 166, 0.3); color: rgb(15, 118, 110);"
|
||||||
|
>
|
||||||
|
{setor.nome}
|
||||||
|
{#if setor.sigla}
|
||||||
|
<span class="text-base-content/60 ml-1">({setor.sigla})</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
{:else if setoresQuery?.isLoading}
|
||||||
|
<p class="text-base-content/50 mt-1 text-sm">Carregando...</p>
|
||||||
|
{:else}
|
||||||
|
<p class="text-base-content/50 mt-1 text-sm">Nenhum setor atribuído</p>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="hover:bg-base-200/60 border-base-300/50 flex items-start gap-3 rounded-lg border p-4 shadow-sm transition-all hover:shadow-md"
|
class="hover:bg-base-200/60 border-base-300/50 flex items-start gap-3 rounded-lg border p-4 shadow-sm transition-all hover:shadow-md"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -79,6 +79,42 @@
|
|||||||
openMenuId = openMenuId === id ? null : id;
|
openMenuId = openMenuId === id ? null : id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function closeMenu() {
|
||||||
|
openMenuId = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fechar menu ao clicar fora
|
||||||
|
$effect(() => {
|
||||||
|
if (!openMenuId) return;
|
||||||
|
|
||||||
|
function handleClickOutside(event: MouseEvent) {
|
||||||
|
const target = event.target as HTMLElement;
|
||||||
|
// Verificar se o clique foi fora do dropdown (botão e menu)
|
||||||
|
const dropdown = target.closest('.dropdown');
|
||||||
|
if (!dropdown) {
|
||||||
|
openMenuId = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleEscape(event: KeyboardEvent) {
|
||||||
|
if (event.key === 'Escape') {
|
||||||
|
openMenuId = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adicionar listeners no próximo tick para não interferir com o clique que abriu o menu
|
||||||
|
const timeoutId = setTimeout(() => {
|
||||||
|
document.addEventListener('click', handleClickOutside);
|
||||||
|
document.addEventListener('keydown', handleEscape);
|
||||||
|
}, 10);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
document.removeEventListener('click', handleClickOutside);
|
||||||
|
document.removeEventListener('keydown', handleEscape);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
async function openSetoresModal(funcionarioId: Id<'funcionarios'>, nome: string) {
|
async function openSetoresModal(funcionarioId: Id<'funcionarios'>, nome: string) {
|
||||||
funcionarioParaSetores = { _id: funcionarioId, nome };
|
funcionarioParaSetores = { _id: funcionarioId, nome };
|
||||||
setoresSelecionados = [];
|
setoresSelecionados = [];
|
||||||
@@ -382,30 +418,50 @@
|
|||||||
class="dropdown-content menu bg-base-100 rounded-box border-base-300 z-20 w-52 border p-2 shadow-xl"
|
class="dropdown-content menu bg-base-100 rounded-box border-base-300 z-20 w-52 border p-2 shadow-xl"
|
||||||
>
|
>
|
||||||
<li>
|
<li>
|
||||||
<a href={resolve(`/recursos-humanos/funcionarios/${f._id}`)} class="hover:bg-primary/10">
|
<a
|
||||||
|
href={resolve(`/recursos-humanos/funcionarios/${f._id}`)}
|
||||||
|
class="hover:bg-primary/10"
|
||||||
|
onclick={closeMenu}
|
||||||
|
>
|
||||||
Ver Detalhes
|
Ver Detalhes
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href={resolve(`/recursos-humanos/funcionarios/${f._id}/editar`)} class="hover:bg-primary/10">
|
<a
|
||||||
|
href={resolve(`/recursos-humanos/funcionarios/${f._id}/editar`)}
|
||||||
|
class="hover:bg-primary/10"
|
||||||
|
onclick={closeMenu}
|
||||||
|
>
|
||||||
Editar
|
Editar
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href={resolve(`/recursos-humanos/funcionarios/${f._id}/documentos`)} class="hover:bg-primary/10">
|
<a
|
||||||
|
href={resolve(`/recursos-humanos/funcionarios/${f._id}/documentos`)}
|
||||||
|
class="hover:bg-primary/10"
|
||||||
|
onclick={closeMenu}
|
||||||
|
>
|
||||||
Ver Documentos
|
Ver Documentos
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<button
|
<button
|
||||||
onclick={() => openSetoresModal(f._id, f.nome)}
|
onclick={() => {
|
||||||
|
openSetoresModal(f._id, f.nome);
|
||||||
|
}}
|
||||||
class="hover:bg-primary/10"
|
class="hover:bg-primary/10"
|
||||||
>
|
>
|
||||||
Atribuir Setores
|
Atribuir Setores
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<button onclick={() => openPrintModal(f._id)} class="hover:bg-primary/10">
|
<button
|
||||||
|
onclick={() => {
|
||||||
|
openPrintModal(f._id);
|
||||||
|
closeMenu();
|
||||||
|
}}
|
||||||
|
class="hover:bg-primary/10"
|
||||||
|
>
|
||||||
Imprimir Ficha
|
Imprimir Ficha
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
Reference in New Issue
Block a user