# crud_definitions/support_ticket_module.yml
# --- Module-level Info (used by `make:module-crud`) ---
name: Ticket
namespace: Support
inertia_crud: # Options for make:inertia-crud
softDeletes: true
vue_form: # Options for make:vue-form
formName: TicketForm
withLayout: true # Use sections for form layout
vue_dataview: # Options for make:vue-dataview
componentName: TicketDetailView
zod_schema: # Options for make:zod-schema
yamlKey: schema_fields # The key in *this file* holding the Zod schema definition
#-------------------------------------------------------------------------------
# ZOD SCHEMA FIELDS DEFINITION
#-------------------------------------------------------------------------------
schema_fields:
- { model: id, type: string }
- { model: subject, type: string, required: true }
- { model: content, type: string, optional: true, nullable: true }
- { model: priority, type: enum, options: [low, medium, high], default: "medium" }
- { model: status, type: string, default: "open" }
- { model: isResolved, type: boolean, default: false }
- { model: assignedAgentId, type: string, nullable: true, optional: true }
- { model: satisfactionRating, type: number, min: 1, max: 5, optional: true, nullable: true }
- { model: reportedAt, type: datetime, default: "now" }
- { model: deadline, type: date, optional: true, nullable: true }
- { model: attachments, type: attachmentupload, optional: true }
- { model: customerSignature, type: signature, optional: true, nullable: true }
- { model: issueLocation, type: location, optional: true, nullable: true }
- { model: affectedArea, type: geofence, optional: true, nullable: true }
- { model: relatedTasks, type: array_object_manager, optional: true }
#-------------------------------------------------------------------------------
# TABLE COLUMN DEFINITIONS (for Index.vue)
#-------------------------------------------------------------------------------
table:
- { name: id, label: "Ticket ID", show: true, sort: true, search: true }
- { name: subject, label: "Subject", show: true, search: true, sort: true }
- { name: status, label: "Status", show: true, filter: true, sort: true, datatype: "statusBadge" }
- { name: priority, label: "Priority", show: true, filter: true, sort: true, datatype: "badge" }
- { name: isResolved, label: "Resolved", show: true, sort: true, datatype: "booleanIcon" }
- { name: assignedAgentName, label: "Agent", show: true, search: true, sort: true } # A related field
- { name: reportedAt, label: "Reported At", show: true, sort: true, datatype: "datetime" }
#-------------------------------------------------------------------------------
# FORM DEFINITION (for Create.vue / Edit.vue)
#-------------------------------------------------------------------------------
form:
- label: "Ticket Details"
name: ticketDetailsSection
type: card
children:
- { label: "Subject", name: subject, model: subject, type: text, validator: "required|min:5", placeholder: "Briefly describe the issue..." }
- { label: "Status", name: status, model: status, type: select, default: "open", param: { options: [{value: 'open', label: 'Open'}, {value: 'in_progress', label: 'In Progress'}, {value: 'closed', label: 'Closed'}] } }
- { label: "Priority", name: priority, model: priority, type: radio, default: "medium", param: { options: [{value: 'low', label: 'Low'}, {value: 'medium', label: 'Medium'}, {value: 'high', label: 'High'}] } }
- { label: "Is Resolved?", name: isResolved, model: isResolved, type: switch }
- { label: "Deadline", name: deadline, model: deadline, type: datepicker }
- label: "Issue Description & Attachments"
name: descriptionSection
type: card
children:
- { label: "Full Description", name: content, model: content, type: textarea, param: { rows: 8 }, placeholder: "Provide a detailed description of the problem, including steps to reproduce." }
- { label: "Attachments", name: attachments, model: attachments, type: attachmentupload, param: { uploadUrl: "/api/upload/ticket-attachments" } }
- { label: "Customer Signature", name: customerSignature, model: customerSignature, type: signature-modal, param: { uploadUrl: "/api/upload/signatures", modalTitle: "Confirm with Signature" } }
- label: "Location & Area"
name: locationSection
type: div
class: "grid grid-cols-1 lg:grid-cols-2 gap-6"
children:
- label: "Issue Location"
name: issueLocation
model: issueLocation
type: location
param: { mapHeight: '300px' }
- label: "Affected Area"
name: affectedArea
model: affectedArea
type: geofence
param: { mapHeight: '300px', allowedShapes: ['polygon', 'circle'] }
- label: "Related Tasks"
name: relatedTasksSection
type: card
children:
- label: "Sub-Tasks"
name: relatedTasks
model: relatedTasks
type: array_object_manager
param:
title: "Manage Sub-Tasks"
itemKey: "uid"
newItemTemplate: { uid: "", title: "", completed: false }
columns:
- { key: "title", label: "Task Title" }
- { key: "completed", label: "Completed", formatter: "formatBoolean" }
#-------------------------------------------------------------------------------
# DATA VIEW DEFINITION (for View.vue)
#-------------------------------------------------------------------------------
view:
- label: "Ticket Overview"
name: ticketOverview
type: card-stacked
children:
- { label: "Subject", model: subject, class: "text-lg font-semibold" }
- { label: "Status", model: status, type: statusBadge }
- { label: "Priority", model: priority, type: badge, param: { variant: "outline" } }
- { label: "Agent", model: assignedAgent.name } # Example of nested data
- { label: "Reported At", model: reportedAt, type: datetime }
- { label: "Deadline", model: deadline, type: date }
- { label: "Resolved", model: isResolved, type: booleanIcon }
- label: "Full Description"
name: descriptionView
type: card
children:
- { label: "", model: content, type: markdown }
- label: "Visual Information"
name: visualInfo
type: div
class: "grid grid-cols-1 lg:grid-cols-2 gap-6"
children:
- label: "Issue Location"
name: issueLocationView
type: map-point
model: issueLocation
param: { mapHeight: "300px" }
- label: "Affected Area"
name: affectedAreaView
type: map-geofence
model: affectedArea
param: { mapHeight: "300px", fitBounds: true }
- label: "Attachments & Signature"
name: attachmentsView
type: card-stacked
children:
- { label: "Attachments", model: attachments, type: attachmentlist }
- { label: "Customer Signature", model: customerSignature, type: image, param: { imageClass: "h-24 w-auto border p-2 bg-white rounded" } }
- label: "Analytics (Chart)"
name: analyticsView
type: chart
model: analyticsData
param:
chartType: bar
xAxis: { dataKey: "day" }
series:
- { dataKey: "interactions", name: "Agent Interactions" }
yAxis: { label: "Count" }