refactor: optimize query handling and state management in perfil page

- Updated query logic to ensure stable data retrieval for user-related information, reducing unnecessary re-creations.
- Implemented derived states to manage loading and error conditions more effectively, enhancing user experience.
- Improved synchronization of query results with stable states, ensuring data consistency during loading phases.
- Refactored existing queries to utilize stable keys based on user IDs, preventing issues with undefined states.
This commit is contained in:
2025-11-18 06:51:22 -03:00
parent 422dc6f022
commit db098ceea9

View File

@@ -83,95 +83,120 @@
// FuncionarioId disponível diretamente do usuário atual
const funcionarioIdDisponivel = $derived(currentUser?.data?.funcionarioId ?? null);
const gestorIdDisponivel = $derived(currentUser?.data?._id ?? null);
// Queries
const funcionarioQuery = $derived(
currentUser?.data?.funcionarioId ? useQuery(api.funcionarios.getCurrent, {}) : { data: null }
);
// ✅ CORRIGIDO: Queries no nível superior (sem argumentos) sempre criadas
// Queries que não requerem argumentos são criadas uma vez
const funcionarioQuery = useQuery(api.funcionarios.getCurrent, {});
const timesSubordinadosQuery = useQuery(api.times.listarSubordinadosDoGestorAtual, {});
const chamadosQuery = useQuery(api.chamados.listarChamadosUsuario, {});
$effect(() => {
if (funcionarioQuery?.data) {
funcionarioEstavel = funcionarioQuery.data;
} else if (!currentUser?.data?.funcionarioId) {
funcionarioEstavel = null;
}
// ✅ CORRIGIDO: Queries com argumentos obrigatórios usando $derived.by para estabilidade
// Usamos uma chave estável baseada no ID para evitar recriação desnecessária
const solicitacoesSubordinadosQuery = $derived.by(() => {
if (!gestorIdDisponivel) return { data: [] };
return useQuery(api.ferias.listarSolicitacoesSubordinados, {
gestorId: gestorIdDisponivel as Id<'usuarios'>
});
});
const solicitacoesSubordinadosQuery = $derived(
currentUser?.data?._id
? useQuery(api.ferias.listarSolicitacoesSubordinados, {
gestorId: currentUser.data._id as Id<'usuarios'>
})
: { data: [] }
);
const ausenciasSubordinadosQuery = $derived.by(() => {
if (!gestorIdDisponivel) return { data: [] };
return useQuery(api.ausencias.listarSolicitacoesSubordinados, {
gestorId: gestorIdDisponivel as Id<'usuarios'>
});
});
const ausenciasSubordinadosQuery = $derived(
currentUser?.data?._id
? useQuery(api.ausencias.listarSolicitacoesSubordinados, {
gestorId: currentUser.data._id as Id<'usuarios'>
})
: { data: [] }
);
// ✅ CORRIGIDO: Estados estáveis atualizados apenas quando há dados válidos
// Não limpamos quando undefined (carregando), apenas quando explicitamente sem dados
$effect(() => {
if (funcionarioQuery?.data && funcionarioIdDisponivel) {
funcionarioEstavel = funcionarioQuery.data;
} else if (
funcionarioQuery !== undefined &&
funcionarioQuery?.data === null &&
!funcionarioIdDisponivel
) {
// Só limpar se a query retornou explicitamente null e não há funcionarioId
funcionarioEstavel = null;
}
// Se funcionarioQuery é undefined, ainda está carregando - manter estado atual
});
const minhasSolicitacoesQuery = $derived(
funcionarioEstavel?._id
? useQuery(api.ferias.listarMinhasSolicitacoes, {
funcionarioId: funcionarioEstavel._id
})
: { data: [] }
);
// Queries que dependem de funcionarioEstavel
const funcionarioIdParaQueries = $derived(funcionarioEstavel?._id ?? null);
const minhasAusenciasQuery = $derived(
funcionarioEstavel?._id
? useQuery(api.ausencias.listarMinhasSolicitacoes, {
funcionarioId: funcionarioEstavel._id
})
: { data: [] }
);
const minhasSolicitacoesQuery = $derived.by(() => {
if (!funcionarioIdParaQueries) return { data: [] };
return useQuery(api.ferias.listarMinhasSolicitacoes, {
funcionarioId: funcionarioIdParaQueries
});
});
const meuTimeQuery = $derived(
funcionarioEstavel?._id
? useQuery(api.times.obterTimeFuncionario, {
funcionarioId: funcionarioEstavel._id
})
: { data: null }
);
const minhasAusenciasQuery = $derived.by(() => {
if (!funcionarioIdParaQueries) return { data: [] };
return useQuery(api.ausencias.listarMinhasSolicitacoes, {
funcionarioId: funcionarioIdParaQueries
});
});
const meuTimeQuery = $derived.by(() => {
if (!funcionarioIdParaQueries) return { data: null };
return useQuery(api.times.obterTimeFuncionario, {
funcionarioId: funcionarioIdParaQueries
});
});
$effect(() => {
if (meuTimeQuery?.data) {
if (meuTimeQuery?.data && funcionarioIdParaQueries) {
meuTimeEstavel = meuTimeQuery.data;
} else if (!funcionarioEstavel?._id) {
} else if (
meuTimeQuery !== undefined &&
meuTimeQuery?.data === null &&
!funcionarioIdParaQueries
) {
meuTimeEstavel = null;
}
});
const funcionario = $derived(funcionarioEstavel);
const solicitacoesSubordinados = $derived(solicitacoesSubordinadosQuery?.data || []);
const ausenciasSubordinados = $derived(ausenciasSubordinadosQuery?.data || []);
const meuTime = $derived(meuTimeEstavel);
$effect(() => {
if (Array.isArray(minhasSolicitacoesQuery?.data)) {
if (Array.isArray(minhasSolicitacoesQuery?.data) && funcionarioIdParaQueries) {
minhasSolicitacoesEstaveis = minhasSolicitacoesQuery.data;
} else if (!funcionarioEstavel?._id) {
} else if (
minhasSolicitacoesQuery !== undefined &&
minhasSolicitacoesQuery?.data === null &&
!funcionarioIdParaQueries
) {
minhasSolicitacoesEstaveis = [];
}
});
$effect(() => {
if (Array.isArray(minhasAusenciasQuery?.data)) {
if (Array.isArray(minhasAusenciasQuery?.data) && funcionarioIdParaQueries) {
minhasAusenciasEstaveis = minhasAusenciasQuery.data;
} else if (!funcionarioEstavel?._id) {
} else if (
minhasAusenciasQuery !== undefined &&
minhasAusenciasQuery?.data === null &&
!funcionarioIdParaQueries
) {
minhasAusenciasEstaveis = [];
}
});
// Deriveds - agora apenas extraem dados, não criam queries
const funcionario = $derived(funcionarioEstavel);
const solicitacoesSubordinados = $derived.by(() => {
if (!gestorIdDisponivel) return [];
return solicitacoesSubordinadosQuery?.data || [];
});
const ausenciasSubordinados = $derived.by(() => {
if (!gestorIdDisponivel) return [];
return ausenciasSubordinadosQuery?.data || [];
});
const meuTime = $derived(meuTimeEstavel);
const minhasSolicitacoes = $derived(minhasSolicitacoesEstaveis);
const minhasAusencias = $derived(minhasAusenciasEstaveis);
const timesSubordinadosQuery = $derived(useQuery(api.times.listarSubordinadosDoGestorAtual, {}));
const timesSubordinados = $derived(timesSubordinadosQuery?.data || []);
// Times gerenciados usam a query que já infere o gestor logado
const meusTimesGestor = $derived(timesSubordinados);
const rolePermiteAprovacao = $derived(
@@ -180,28 +205,26 @@
const ehGestor = $derived((timesSubordinados || []).length > 0 || rolePermiteAprovacao);
// Query reativa para Meus Chamados (igual às outras abas)
const chamadosQuery = $derived(
currentUser?.data?._id ? useQuery(api.chamados.listarChamadosUsuario, {}) : null
);
// Estados estáveis para Meus Chamados (igual às outras abas)
// Estados estáveis para Meus Chamados
let chamadosEstaveis = $state<Array<Doc<'tickets'>>>([]);
// Sincronizar query com estado estável (igual às outras abas)
// ✅ CORRIGIDO: Sincronizar query com estado estável preservando durante carregamento
$effect(() => {
if (chamadosQuery && Array.isArray(chamadosQuery.data)) {
if (chamadosQuery && Array.isArray(chamadosQuery.data) && gestorIdDisponivel) {
chamadosEstaveis = chamadosQuery.data;
// Sincronizar com a store para compatibilidade
chamadosStore.setTickets(chamadosQuery.data);
// Selecionar primeiro chamado automaticamente se não houver seleção
if (!selectedTicketId && chamadosQuery.data.length > 0) {
selectedTicketId = chamadosQuery.data[0]._id;
}
} else if (!currentUser?.data?._id) {
} else if (
chamadosQuery !== undefined &&
chamadosQuery?.data === null &&
!gestorIdDisponivel
) {
chamadosEstaveis = [];
chamadosStore.setTickets([]);
}
// Se chamadosQuery é undefined, ainda está carregando - manter estado atual
});
// Deriveds para Meus Chamados