feat(checklist): adiciona tipo pergunta e descricao nos itens
- Adiciona campo `type` (checkbox/question) nos itens do checklist - Adiciona campo `description` para descricao do item - Adiciona campo `options` para opcoes de resposta em perguntas - Adiciona campo `answer` para resposta selecionada - Atualiza UI para mostrar descricao e opcoes de pergunta - Cria componente radio-group para selecao de respostas - Adiciona mutation setChecklistItemAnswer para salvar respostas 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
98b23af4b2
commit
0f3ba07a5e
10 changed files with 446 additions and 76 deletions
|
|
@ -14,17 +14,37 @@ function normalizeTemplateDescription(input: string | null | undefined) {
|
|||
return text.length > 0 ? text : null
|
||||
}
|
||||
|
||||
type ChecklistItemType = "checkbox" | "question"
|
||||
|
||||
type RawTemplateItem = {
|
||||
id?: string
|
||||
text: string
|
||||
description?: string
|
||||
type?: string
|
||||
options?: string[]
|
||||
required?: boolean
|
||||
}
|
||||
|
||||
type NormalizedTemplateItem = {
|
||||
id: string
|
||||
text: string
|
||||
description?: string
|
||||
type?: ChecklistItemType
|
||||
options?: string[]
|
||||
required?: boolean
|
||||
}
|
||||
|
||||
function normalizeTemplateItems(
|
||||
raw: Array<{ id?: string; text: string; required?: boolean }>,
|
||||
raw: RawTemplateItem[],
|
||||
options: { generateId?: () => string }
|
||||
) {
|
||||
): NormalizedTemplateItem[] {
|
||||
if (!Array.isArray(raw) || raw.length === 0) {
|
||||
throw new ConvexError("Adicione pelo menos um item no checklist.")
|
||||
}
|
||||
|
||||
const generateId = options.generateId ?? (() => crypto.randomUUID())
|
||||
const seen = new Set<string>()
|
||||
const items: Array<{ id: string; text: string; required?: boolean }> = []
|
||||
const items: NormalizedTemplateItem[] = []
|
||||
|
||||
for (const entry of raw) {
|
||||
const id = String(entry.id ?? "").trim() || generateId()
|
||||
|
|
@ -38,11 +58,28 @@ function normalizeTemplateItems(
|
|||
throw new ConvexError("Todos os itens do checklist precisam ter um texto.")
|
||||
}
|
||||
if (text.length > 240) {
|
||||
throw new ConvexError("Item do checklist muito longo (máx. 240 caracteres).")
|
||||
throw new ConvexError("Item do checklist muito longo (max. 240 caracteres).")
|
||||
}
|
||||
|
||||
const description = entry.description?.trim() || undefined
|
||||
const itemType: ChecklistItemType = entry.type === "question" ? "question" : "checkbox"
|
||||
const itemOptions = itemType === "question" && Array.isArray(entry.options)
|
||||
? entry.options.map((o) => String(o).trim()).filter((o) => o.length > 0)
|
||||
: undefined
|
||||
|
||||
if (itemType === "question" && (!itemOptions || itemOptions.length < 2)) {
|
||||
throw new ConvexError(`A pergunta "${text}" precisa ter pelo menos 2 opcoes.`)
|
||||
}
|
||||
|
||||
const required = typeof entry.required === "boolean" ? entry.required : true
|
||||
items.push({ id, text, required })
|
||||
items.push({
|
||||
id,
|
||||
text,
|
||||
description,
|
||||
type: itemType,
|
||||
options: itemOptions,
|
||||
required,
|
||||
})
|
||||
}
|
||||
|
||||
return items
|
||||
|
|
@ -57,6 +94,9 @@ function mapTemplate(template: Doc<"ticketChecklistTemplates">, company: Doc<"co
|
|||
items: (template.items ?? []).map((item) => ({
|
||||
id: item.id,
|
||||
text: item.text,
|
||||
description: item.description,
|
||||
type: item.type ?? "checkbox",
|
||||
options: item.options,
|
||||
required: typeof item.required === "boolean" ? item.required : true,
|
||||
})),
|
||||
isArchived: Boolean(template.isArchived),
|
||||
|
|
@ -164,6 +204,9 @@ export const create = mutation({
|
|||
v.object({
|
||||
id: v.optional(v.string()),
|
||||
text: v.string(),
|
||||
description: v.optional(v.string()),
|
||||
type: v.optional(v.string()),
|
||||
options: v.optional(v.array(v.string())),
|
||||
required: v.optional(v.boolean()),
|
||||
}),
|
||||
),
|
||||
|
|
@ -216,6 +259,9 @@ export const update = mutation({
|
|||
v.object({
|
||||
id: v.optional(v.string()),
|
||||
text: v.string(),
|
||||
description: v.optional(v.string()),
|
||||
type: v.optional(v.string()),
|
||||
options: v.optional(v.array(v.string())),
|
||||
required: v.optional(v.boolean()),
|
||||
}),
|
||||
),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue