feat: enhance file upload component and backend schema

- Updated the FileUpload component to improve file handling and state management, including better cancellation logic and input handling.
- Added a new alias in the Svelte configuration for easier backend access.
- Enhanced the backend schema to include a gestorSuperiorId for better team management and query capabilities.
- Refactored queries and mutations in the backend to support the new structure and improve data retrieval for subordinate teams.
This commit is contained in:
2025-11-14 22:11:06 -03:00
parent 731f95d0b5
commit 9b3b095c01
6 changed files with 278 additions and 161 deletions

View File

@@ -299,9 +299,12 @@ export default defineSchema({
nome: v.string(),
descricao: v.optional(v.string()),
gestorId: v.id("usuarios"),
gestorSuperiorId: v.optional(v.id("usuarios")),
ativo: v.boolean(),
cor: v.optional(v.string()), // Cor para identificação visual
}).index("by_gestor", ["gestorId"]),
})
.index("by_gestor", ["gestorId"])
.index("by_gestor_superior", ["gestorSuperiorId"]),
timesMembros: defineTable({
timeId: v.id("times"),

View File

@@ -1,6 +1,6 @@
import { v } from "convex/values";
import { mutation, query } from "./_generated/server";
import { Id, Doc } from "./_generated/dataModel";
import { getCurrentUserFunction } from "./auth";
// Query: Listar todos os times
// Tipo inferido automaticamente pelo Convex
@@ -127,12 +127,67 @@ export const listarPorGestor = query({
},
});
export const listarSubordinadosDoGestorAtual = query({
args: {},
handler: async (ctx) => {
const usuario = await getCurrentUserFunction(ctx);
if (!usuario) {
return [];
}
const timesGestor = await ctx.db
.query("times")
.withIndex("by_gestor", (q) => q.eq("gestorId", usuario._id))
.collect();
const timesComoSuperior = await ctx.db
.query("times")
.withIndex("by_gestor_superior", (q) => q.eq("gestorSuperiorId", usuario._id))
.collect();
const timesMap = new Map(
[...timesGestor, ...timesComoSuperior]
.filter((time) => time.ativo)
.map((time) => [time._id, time])
);
const resultado = [];
for (const time of timesMap.values()) {
const membrosRelacoes = await ctx.db
.query("timesMembros")
.withIndex("by_time_and_ativo", (q) => q.eq("timeId", time._id).eq("ativo", true))
.collect();
const membros = [];
for (const rel of membrosRelacoes) {
const funcionario = await ctx.db.get(rel.funcionarioId);
if (funcionario) {
membros.push({
relacaoId: rel._id,
funcionario,
dataEntrada: rel.dataEntrada,
});
}
}
resultado.push({
...time,
membros,
});
}
return resultado;
},
});
// Mutation: Criar time
export const criar = mutation({
args: {
nome: v.string(),
descricao: v.optional(v.string()),
gestorId: v.id("usuarios"),
gestorSuperiorId: v.optional(v.id("usuarios")),
cor: v.optional(v.string()),
},
returns: v.id("times"),
@@ -141,6 +196,7 @@ export const criar = mutation({
nome: args.nome,
descricao: args.descricao,
gestorId: args.gestorId,
gestorSuperiorId: args.gestorSuperiorId ?? args.gestorId,
ativo: true,
cor: args.cor || "#3B82F6",
});
@@ -156,12 +212,16 @@ export const atualizar = mutation({
nome: v.string(),
descricao: v.optional(v.string()),
gestorId: v.id("usuarios"),
gestorSuperiorId: v.optional(v.id("usuarios")),
cor: v.optional(v.string()),
},
returns: v.null(),
handler: async (ctx, args) => {
const { id, ...dados } = args;
await ctx.db.patch(id, dados);
await ctx.db.patch(id, {
...dados,
gestorSuperiorId: dados.gestorSuperiorId ?? dados.gestorId,
});
return null;
},
});
@@ -185,6 +245,8 @@ export const desativar = mutation({
ativo: false,
dataSaida: Date.now(),
});
await ctx.db.patch(membro.funcionarioId, { gestorId: undefined });
}
return null;
@@ -210,12 +272,19 @@ export const adicionarMembro = mutation({
throw new Error("Funcionário já está em um time ativo");
}
const time = await ctx.db.get(args.timeId);
if (!time || !time.ativo) {
throw new Error("Time inválido ou inativo");
}
const membroId = await ctx.db.insert("timesMembros", {
timeId: args.timeId,
funcionarioId: args.funcionarioId,
dataEntrada: Date.now(),
ativo: true,
});
await ctx.db.patch(args.funcionarioId, { gestorId: time.gestorId });
return membroId;
},
@@ -226,10 +295,16 @@ export const removerMembro = mutation({
args: { membroId: v.id("timesMembros") },
returns: v.null(),
handler: async (ctx, args) => {
const membro = await ctx.db.get(args.membroId);
if (!membro) {
throw new Error("Membro não encontrado");
}
await ctx.db.patch(args.membroId, {
ativo: false,
dataSaida: Date.now(),
});
await ctx.db.patch(membro.funcionarioId, { gestorId: undefined });
return null;
},
});
@@ -257,12 +332,19 @@ export const transferirMembro = mutation({
}
// Adicionar ao novo time
const novoTime = await ctx.db.get(args.novoTimeId);
if (!novoTime || !novoTime.ativo) {
throw new Error("Novo time inválido ou inativo");
}
await ctx.db.insert("timesMembros", {
timeId: args.novoTimeId,
funcionarioId: args.funcionarioId,
dataEntrada: Date.now(),
ativo: true,
});
await ctx.db.patch(args.funcionarioId, { gestorId: novoTime.gestorId });
return null;
},