- Adiciona checklist no ticket (itens obrigatórios/opcionais) e bloqueia encerramento com pendências\n- Cria templates de checklist (globais/por empresa) + tela em /settings/checklists\n- Nova ação de automação: aplicar template de checklist\n- Corrige crash do Select (value vazio), warnings de Dialog e dimensionamento de charts\n- Ajusta SMTP (STARTTLS) e melhora teste de integração
71 lines
2 KiB
TypeScript
71 lines
2 KiB
TypeScript
import type { Id } from "./_generated/dataModel"
|
|
|
|
export type TicketChecklistItem = {
|
|
id: string
|
|
text: string
|
|
done: boolean
|
|
required?: boolean
|
|
templateId?: Id<"ticketChecklistTemplates">
|
|
templateItemId?: string
|
|
createdAt?: number
|
|
createdBy?: Id<"users">
|
|
doneAt?: number
|
|
doneBy?: Id<"users">
|
|
}
|
|
|
|
export type TicketChecklistTemplateLike = {
|
|
_id: Id<"ticketChecklistTemplates">
|
|
items: Array<{ id: string; text: string; required?: boolean }>
|
|
}
|
|
|
|
export function normalizeChecklistText(input: string) {
|
|
return input.replace(/\r\n/g, "\n").trim()
|
|
}
|
|
|
|
export function checklistBlocksResolution(checklist: TicketChecklistItem[] | null | undefined) {
|
|
return (checklist ?? []).some((item) => (item.required ?? true) && item.done !== true)
|
|
}
|
|
|
|
export function applyChecklistTemplateToItems(
|
|
existing: TicketChecklistItem[],
|
|
template: TicketChecklistTemplateLike,
|
|
options: {
|
|
now: number
|
|
actorId?: Id<"users">
|
|
generateId?: () => string
|
|
}
|
|
) {
|
|
const generateId = options.generateId ?? (() => crypto.randomUUID())
|
|
const now = options.now
|
|
|
|
const next = Array.isArray(existing) ? [...existing] : []
|
|
const existingKeys = new Set<string>()
|
|
for (const item of next) {
|
|
if (!item.templateId || !item.templateItemId) continue
|
|
existingKeys.add(`${String(item.templateId)}:${item.templateItemId}`)
|
|
}
|
|
|
|
let added = 0
|
|
for (const tplItem of template.items ?? []) {
|
|
const templateItemId = String(tplItem.id ?? "").trim()
|
|
const text = normalizeChecklistText(String(tplItem.text ?? ""))
|
|
if (!templateItemId || !text) continue
|
|
const key = `${String(template._id)}:${templateItemId}`
|
|
if (existingKeys.has(key)) continue
|
|
existingKeys.add(key)
|
|
next.push({
|
|
id: generateId(),
|
|
text,
|
|
done: false,
|
|
required: typeof tplItem.required === "boolean" ? tplItem.required : true,
|
|
templateId: template._id,
|
|
templateItemId,
|
|
createdAt: now,
|
|
createdBy: options.actorId,
|
|
})
|
|
added += 1
|
|
}
|
|
|
|
return { checklist: next, added }
|
|
}
|
|
|