feat: add Svelte DnD action and enhance flow management features
- Added "svelte-dnd-action" dependency to facilitate drag-and-drop functionality. - Introduced new "Fluxos de Trabalho" section in the dashboard for managing workflow templates and instances. - Updated permission handling for sectors and flow templates in the backend. - Enhanced schema definitions to support flow templates, instances, and associated documents. - Improved UI components to include new workflow management features across various dashboard pages.
This commit is contained in:
178
packages/backend/convex/setores.ts
Normal file
178
packages/backend/convex/setores.ts
Normal file
@@ -0,0 +1,178 @@
|
||||
import { query, mutation } from './_generated/server';
|
||||
import { v } from 'convex/values';
|
||||
import { getCurrentUserFunction } from './auth';
|
||||
|
||||
/**
|
||||
* Listar todos os setores
|
||||
*/
|
||||
export const list = query({
|
||||
args: {},
|
||||
returns: v.array(
|
||||
v.object({
|
||||
_id: v.id('setores'),
|
||||
_creationTime: v.number(),
|
||||
nome: v.string(),
|
||||
sigla: v.string(),
|
||||
criadoPor: v.id('usuarios'),
|
||||
createdAt: v.number()
|
||||
})
|
||||
),
|
||||
handler: async (ctx) => {
|
||||
const setores = await ctx.db.query('setores').order('asc').collect();
|
||||
return setores;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Obter um setor pelo ID
|
||||
*/
|
||||
export const getById = query({
|
||||
args: { id: v.id('setores') },
|
||||
returns: v.union(
|
||||
v.object({
|
||||
_id: v.id('setores'),
|
||||
_creationTime: v.number(),
|
||||
nome: v.string(),
|
||||
sigla: v.string(),
|
||||
criadoPor: v.id('usuarios'),
|
||||
createdAt: v.number()
|
||||
}),
|
||||
v.null()
|
||||
),
|
||||
handler: async (ctx, args) => {
|
||||
const setor = await ctx.db.get(args.id);
|
||||
return setor;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Criar um novo setor
|
||||
*/
|
||||
export const create = mutation({
|
||||
args: {
|
||||
nome: v.string(),
|
||||
sigla: v.string()
|
||||
},
|
||||
returns: v.id('setores'),
|
||||
handler: async (ctx, args) => {
|
||||
const usuario = await getCurrentUserFunction(ctx);
|
||||
if (!usuario) {
|
||||
throw new Error('Usuário não autenticado');
|
||||
}
|
||||
|
||||
// Verificar se já existe setor com mesmo nome ou sigla
|
||||
const existenteNome = await ctx.db
|
||||
.query('setores')
|
||||
.withIndex('by_nome', (q) => q.eq('nome', args.nome))
|
||||
.first();
|
||||
if (existenteNome) {
|
||||
throw new Error('Já existe um setor com este nome');
|
||||
}
|
||||
|
||||
const existenteSigla = await ctx.db
|
||||
.query('setores')
|
||||
.withIndex('by_sigla', (q) => q.eq('sigla', args.sigla))
|
||||
.first();
|
||||
if (existenteSigla) {
|
||||
throw new Error('Já existe um setor com esta sigla');
|
||||
}
|
||||
|
||||
const setorId = await ctx.db.insert('setores', {
|
||||
nome: args.nome,
|
||||
sigla: args.sigla.toUpperCase(),
|
||||
criadoPor: usuario._id,
|
||||
createdAt: Date.now()
|
||||
});
|
||||
|
||||
return setorId;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Atualizar um setor existente
|
||||
*/
|
||||
export const update = mutation({
|
||||
args: {
|
||||
id: v.id('setores'),
|
||||
nome: v.string(),
|
||||
sigla: v.string()
|
||||
},
|
||||
returns: v.null(),
|
||||
handler: async (ctx, args) => {
|
||||
const usuario = await getCurrentUserFunction(ctx);
|
||||
if (!usuario) {
|
||||
throw new Error('Usuário não autenticado');
|
||||
}
|
||||
|
||||
const setor = await ctx.db.get(args.id);
|
||||
if (!setor) {
|
||||
throw new Error('Setor não encontrado');
|
||||
}
|
||||
|
||||
// Verificar se já existe outro setor com mesmo nome
|
||||
const existenteNome = await ctx.db
|
||||
.query('setores')
|
||||
.withIndex('by_nome', (q) => q.eq('nome', args.nome))
|
||||
.first();
|
||||
if (existenteNome && existenteNome._id !== args.id) {
|
||||
throw new Error('Já existe um setor com este nome');
|
||||
}
|
||||
|
||||
// Verificar se já existe outro setor com mesma sigla
|
||||
const existenteSigla = await ctx.db
|
||||
.query('setores')
|
||||
.withIndex('by_sigla', (q) => q.eq('sigla', args.sigla))
|
||||
.first();
|
||||
if (existenteSigla && existenteSigla._id !== args.id) {
|
||||
throw new Error('Já existe um setor com esta sigla');
|
||||
}
|
||||
|
||||
await ctx.db.patch(args.id, {
|
||||
nome: args.nome,
|
||||
sigla: args.sigla.toUpperCase()
|
||||
});
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Excluir um setor
|
||||
*/
|
||||
export const remove = mutation({
|
||||
args: { id: v.id('setores') },
|
||||
returns: v.null(),
|
||||
handler: async (ctx, args) => {
|
||||
const usuario = await getCurrentUserFunction(ctx);
|
||||
if (!usuario) {
|
||||
throw new Error('Usuário não autenticado');
|
||||
}
|
||||
|
||||
const setor = await ctx.db.get(args.id);
|
||||
if (!setor) {
|
||||
throw new Error('Setor não encontrado');
|
||||
}
|
||||
|
||||
// Verificar se há funcionários vinculados
|
||||
const funcionariosVinculados = await ctx.db
|
||||
.query('funcionarios')
|
||||
.withIndex('by_setor', (q) => q.eq('setorId', args.id))
|
||||
.first();
|
||||
if (funcionariosVinculados) {
|
||||
throw new Error('Não é possível excluir um setor com funcionários vinculados');
|
||||
}
|
||||
|
||||
// Verificar se há passos de fluxo vinculados
|
||||
const passosVinculados = await ctx.db
|
||||
.query('flowSteps')
|
||||
.collect();
|
||||
const temPassosVinculados = passosVinculados.some((p) => p.setorId === args.id);
|
||||
if (temPassosVinculados) {
|
||||
throw new Error('Não é possível excluir um setor vinculado a passos de fluxo');
|
||||
}
|
||||
|
||||
await ctx.db.delete(args.id);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user