feat(export,tickets,forms,emails):\n- Corrige scroll de Dialogs e melhora UI de seleção de colunas (ícones e separador)\n- Ajusta rota/params da exportação em massa e adiciona modal de exportação individual\n- Renomeia 'Chamado padrão' para 'Chamado' e garante visibilidade total para admin/agente\n- Adiciona toggles por empresa/usuário para habilitar Admissão/Desligamento\n- Exibe badge do tipo de solicitação na listagem e no cabeçalho do ticket\n- Prepara notificações por e-mail (comentário público e encerramento) via SMTP\n
This commit is contained in:
parent
a8333c010f
commit
06deb99bcd
12 changed files with 543 additions and 17 deletions
|
|
@ -1,5 +1,6 @@
|
|||
// CI touch: enable server-side assignee filtering and trigger redeploy
|
||||
import { mutation, query } from "./_generated/server";
|
||||
import { api } from "./_generated/api";
|
||||
import type { MutationCtx, QueryCtx } from "./_generated/server";
|
||||
import { ConvexError, v } from "convex/values";
|
||||
import { Id, type Doc, type DataModel } from "./_generated/dataModel";
|
||||
|
|
@ -1235,6 +1236,7 @@ export const list = query({
|
|||
priority: t.priority,
|
||||
channel: t.channel,
|
||||
queue: queueName,
|
||||
formTemplate: t.formTemplate ?? null,
|
||||
company: company
|
||||
? { id: company._id, name: company.name, isAvulso: company.isAvulso ?? false }
|
||||
: t.companyId || t.companySnapshot
|
||||
|
|
@ -1887,6 +1889,20 @@ export const addComment = mutation({
|
|||
});
|
||||
// bump ticket updatedAt
|
||||
await ctx.db.patch(args.ticketId, { updatedAt: now });
|
||||
// Notificação por e-mail: comentário público para o solicitante
|
||||
try {
|
||||
const snapshotEmail = (ticketDoc.requesterSnapshot as { email?: string } | undefined)?.email
|
||||
if (requestedVisibility === "PUBLIC" && snapshotEmail && String(ticketDoc.requesterId) !== String(args.authorId)) {
|
||||
await ctx.scheduler.runAfter(0, api.ticketNotifications.sendPublicCommentEmail, {
|
||||
to: snapshotEmail,
|
||||
ticketId: String(ticketDoc._id),
|
||||
reference: ticketDoc.reference ?? 0,
|
||||
subject: ticketDoc.subject ?? "",
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn("[tickets] Falha ao agendar e-mail de comentário", e)
|
||||
}
|
||||
return id;
|
||||
},
|
||||
});
|
||||
|
|
@ -2122,6 +2138,22 @@ export async function resolveTicketHandler(
|
|||
createdAt: now,
|
||||
})
|
||||
|
||||
// Notificação por e-mail: encerramento do chamado
|
||||
try {
|
||||
const requesterDoc = await ctx.db.get(ticketDoc.requesterId)
|
||||
const email = (requesterDoc as Doc<"users"> | null)?.email || (ticketDoc.requesterSnapshot as { email?: string } | undefined)?.email || null
|
||||
if (email) {
|
||||
await ctx.scheduler.runAfter(0, api.ticketNotifications.sendResolvedEmail, {
|
||||
to: email,
|
||||
ticketId: String(ticketId),
|
||||
reference: ticketDoc.reference ?? 0,
|
||||
subject: ticketDoc.subject ?? "",
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn("[tickets] Falha ao agendar e-mail de encerramento", e)
|
||||
}
|
||||
|
||||
for (const rel of linkedTickets) {
|
||||
const existing = new Set<string>((rel.relatedTicketIds ?? []).map((value) => String(value)))
|
||||
existing.add(String(ticketId))
|
||||
|
|
@ -2433,10 +2465,14 @@ export const listTicketForms = query({
|
|||
}>
|
||||
|
||||
for (const template of TICKET_FORM_CONFIG) {
|
||||
const enabled = resolveFormEnabled(template.key, template.defaultEnabled, settings as Doc<"ticketFormSettings">[], {
|
||||
let enabled = resolveFormEnabled(template.key, template.defaultEnabled, settings as Doc<"ticketFormSettings">[], {
|
||||
companyId: viewerCompanyId,
|
||||
userId: viewer.user._id,
|
||||
})
|
||||
const viewerRole = (viewer.role ?? "").toUpperCase()
|
||||
if (viewerRole === "ADMIN" || viewerRole === "AGENT") {
|
||||
enabled = true
|
||||
}
|
||||
if (!enabled) {
|
||||
continue
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue