refactor: enhance role management UI and integrate profile management features
- Introduced a modal for managing user profiles, allowing for the creation and editing of profiles with improved state management. - Updated the role filtering logic to enhance type safety and readability. - Refactored UI components for better user experience, including improved button states and loading indicators. - Removed outdated code related to permissions and streamlined the overall structure for maintainability.
This commit is contained in:
@@ -128,36 +128,69 @@ export const listar = query({
|
||||
matricula: v.optional(v.string()),
|
||||
ativo: v.optional(v.boolean()),
|
||||
},
|
||||
returns: v.array(
|
||||
v.object({
|
||||
_id: v.id("usuarios"),
|
||||
matricula: v.string(),
|
||||
nome: v.string(),
|
||||
email: v.string(),
|
||||
ativo: v.boolean(),
|
||||
bloqueado: v.optional(v.boolean()),
|
||||
motivoBloqueio: v.optional(v.string()),
|
||||
primeiroAcesso: v.boolean(),
|
||||
ultimoAcesso: v.optional(v.number()),
|
||||
criadoEm: v.number(),
|
||||
role: v.object({
|
||||
_id: v.id("roles"),
|
||||
nome: v.string(),
|
||||
nivel: v.number(),
|
||||
setor: v.optional(v.string()),
|
||||
}),
|
||||
funcionario: v.optional(
|
||||
v.object({
|
||||
_id: v.id("funcionarios"),
|
||||
nome: v.string(),
|
||||
simboloTipo: v.union(
|
||||
v.literal("cargo_comissionado"),
|
||||
v.literal("funcao_gratificada")
|
||||
),
|
||||
})
|
||||
),
|
||||
})
|
||||
),
|
||||
// returns: v.array(
|
||||
// v.object({
|
||||
// _id: v.id("usuarios"),
|
||||
// matricula: v.string(),
|
||||
// nome: v.string(),
|
||||
// email: v.string(),
|
||||
// ativo: v.boolean(),
|
||||
// bloqueado: v.optional(v.boolean()),
|
||||
// motivoBloqueio: v.optional(v.string()),
|
||||
// primeiroAcesso: v.boolean(),
|
||||
// ultimoAcesso: v.optional(v.number()),
|
||||
// criadoEm: v.number(),
|
||||
// role: v.union(
|
||||
// v.object({
|
||||
// _id: v.id("roles"),
|
||||
// _creationTime: v.optional(v.number()),
|
||||
// criadoPor: v.optional(v.id("usuarios")),
|
||||
// customizado: v.optional(v.boolean()),
|
||||
// descricao: v.string(),
|
||||
// editavel: v.optional(v.boolean()),
|
||||
// nome: v.string(),
|
||||
// nivel: v.number(),
|
||||
// setor: v.optional(v.string()),
|
||||
// }),
|
||||
// v.object({
|
||||
// _id: v.id("roles"),
|
||||
// _creationTime: v.optional(v.number()),
|
||||
// criadoPor: v.optional(v.id("usuarios")),
|
||||
// customizado: v.optional(v.boolean()),
|
||||
// descricao: v.literal("Perfil não encontrado"),
|
||||
// editavel: v.optional(v.boolean()),
|
||||
// nome: v.literal("erro_role_ausente"),
|
||||
// nivel: v.literal(999),
|
||||
// setor: v.optional(v.string()),
|
||||
// erro: v.literal(true),
|
||||
// })
|
||||
// ),
|
||||
// funcionario: v.optional(
|
||||
// v.object({
|
||||
// _id: v.id("funcionarios"),
|
||||
// nome: v.string(),
|
||||
// matricula: v.optional(v.string()),
|
||||
// descricaoCargo: v.optional(v.string()),
|
||||
// simboloTipo: v.union(
|
||||
// v.literal("cargo_comissionado"),
|
||||
// v.literal("funcao_gratificada")
|
||||
// ),
|
||||
// })
|
||||
// ),
|
||||
// avisos: v.optional(
|
||||
// v.array(
|
||||
// v.object({
|
||||
// tipo: v.union(
|
||||
// v.literal("erro"),
|
||||
// v.literal("aviso"),
|
||||
// v.literal("info")
|
||||
// ),
|
||||
// mensagem: v.string(),
|
||||
// })
|
||||
// )
|
||||
// ),
|
||||
// })
|
||||
// ),
|
||||
handler: async (ctx, args) => {
|
||||
let usuarios = await ctx.db.query("usuarios").collect();
|
||||
|
||||
@@ -173,46 +206,136 @@ export const listar = query({
|
||||
|
||||
// Buscar roles e funcionários
|
||||
const resultado = [];
|
||||
const usuariosSemRole: Array<{ nome: string; matricula: string; roleId: Id<"roles"> }> = [];
|
||||
|
||||
for (const usuario of usuarios) {
|
||||
const role = await ctx.db.get(usuario.roleId);
|
||||
if (!role) continue;
|
||||
try {
|
||||
const role = await ctx.db.get(usuario.roleId);
|
||||
|
||||
// Se a role não existe, criar uma role de erro mas ainda incluir o usuário
|
||||
if (!role) {
|
||||
usuariosSemRole.push({
|
||||
nome: usuario.nome,
|
||||
matricula: usuario.matricula,
|
||||
roleId: usuario.roleId,
|
||||
});
|
||||
|
||||
// Filtrar por setor - se filtro está ativo e role não existe, pular
|
||||
if (args.setor) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Filtrar por setor
|
||||
if (args.setor && role.setor !== args.setor) {
|
||||
continue;
|
||||
}
|
||||
// Incluir usuário com role de erro
|
||||
let funcionario = undefined;
|
||||
if (usuario.funcionarioId) {
|
||||
try {
|
||||
const func = await ctx.db.get(usuario.funcionarioId);
|
||||
if (func) {
|
||||
funcionario = {
|
||||
_id: func._id,
|
||||
nome: func.nome,
|
||||
matricula: func.matricula,
|
||||
descricaoCargo: func.descricaoCargo,
|
||||
simboloTipo: func.simboloTipo,
|
||||
};
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Erro ao buscar funcionário ${usuario.funcionarioId} para usuário ${usuario._id}:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
let funcionario = undefined;
|
||||
if (usuario.funcionarioId) {
|
||||
const func = await ctx.db.get(usuario.funcionarioId);
|
||||
if (func) {
|
||||
funcionario = {
|
||||
_id: func._id,
|
||||
nome: func.nome,
|
||||
simboloTipo: func.simboloTipo,
|
||||
};
|
||||
// Criar role de erro (sem _creationTime pois a role não existe)
|
||||
resultado.push({
|
||||
_id: usuario._id,
|
||||
matricula: usuario.matricula,
|
||||
nome: usuario.nome,
|
||||
email: usuario.email,
|
||||
ativo: usuario.ativo,
|
||||
bloqueado: usuario.bloqueado,
|
||||
motivoBloqueio: usuario.motivoBloqueio,
|
||||
primeiroAcesso: usuario.primeiroAcesso,
|
||||
ultimoAcesso: usuario.ultimoAcesso,
|
||||
criadoEm: usuario.criadoEm,
|
||||
role: {
|
||||
_id: usuario.roleId,
|
||||
descricao: "Perfil não encontrado" as const,
|
||||
nome: "erro_role_ausente" as const,
|
||||
nivel: 999 as const,
|
||||
erro: true as const,
|
||||
},
|
||||
funcionario,
|
||||
avisos: [
|
||||
{
|
||||
tipo: "erro" as const,
|
||||
mensagem: `Perfil de acesso (ID: ${usuario.roleId}) não encontrado. Este usuário precisa ter seu perfil reatribuído.`,
|
||||
},
|
||||
],
|
||||
});
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
resultado.push({
|
||||
_id: usuario._id,
|
||||
matricula: usuario.matricula,
|
||||
nome: usuario.nome,
|
||||
email: usuario.email,
|
||||
ativo: usuario.ativo,
|
||||
bloqueado: usuario.bloqueado,
|
||||
motivoBloqueio: usuario.motivoBloqueio,
|
||||
primeiroAcesso: usuario.primeiroAcesso,
|
||||
ultimoAcesso: usuario.ultimoAcesso,
|
||||
criadoEm: usuario.criadoEm,
|
||||
role: {
|
||||
// Filtrar por setor
|
||||
if (args.setor && role.setor !== args.setor) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Buscar funcionário associado
|
||||
let funcionario = undefined;
|
||||
if (usuario.funcionarioId) {
|
||||
try {
|
||||
const func = await ctx.db.get(usuario.funcionarioId);
|
||||
if (func) {
|
||||
funcionario = {
|
||||
_id: func._id,
|
||||
nome: func.nome,
|
||||
matricula: func.matricula,
|
||||
descricaoCargo: func.descricaoCargo,
|
||||
simboloTipo: func.simboloTipo,
|
||||
};
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Erro ao buscar funcionário ${usuario.funcionarioId} para usuário ${usuario._id}:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
// Construir objeto role - incluir _creationTime se existir (campo automático do Convex)
|
||||
const roleObj = {
|
||||
_id: role._id,
|
||||
descricao: role.descricao,
|
||||
nome: role.nome,
|
||||
nivel: role.nivel,
|
||||
setor: role.setor,
|
||||
},
|
||||
funcionario,
|
||||
});
|
||||
...(role.criadoPor !== undefined && { criadoPor: role.criadoPor }),
|
||||
...(role.customizado !== undefined && { customizado: role.customizado }),
|
||||
...(role.editavel !== undefined && { editavel: role.editavel }),
|
||||
...(role.setor !== undefined && { setor: role.setor }),
|
||||
};
|
||||
|
||||
resultado.push({
|
||||
_id: usuario._id,
|
||||
matricula: usuario.matricula,
|
||||
nome: usuario.nome,
|
||||
email: usuario.email,
|
||||
ativo: usuario.ativo,
|
||||
bloqueado: usuario.bloqueado,
|
||||
motivoBloqueio: usuario.motivoBloqueio,
|
||||
primeiroAcesso: usuario.primeiroAcesso,
|
||||
ultimoAcesso: usuario.ultimoAcesso,
|
||||
criadoEm: usuario.criadoEm,
|
||||
role: roleObj,
|
||||
funcionario,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(`Erro ao processar usuário ${usuario._id}:`, error);
|
||||
// Continua processando outros usuários mesmo se houver erro em um
|
||||
}
|
||||
}
|
||||
|
||||
// Log de usuários sem role para depuração
|
||||
if (usuariosSemRole.length > 0) {
|
||||
console.warn(
|
||||
`⚠️ Encontrados ${usuariosSemRole.length} usuário(s) com perfil ausente:`,
|
||||
usuariosSemRole.map((u) => `${u.nome} (${u.matricula}) - RoleID: ${u.roleId}`)
|
||||
);
|
||||
}
|
||||
|
||||
return resultado;
|
||||
|
||||
Reference in New Issue
Block a user