@open-mercato/core 0.6.5-develop.5382.1.f542de69af → 0.6.6-develop.5412.1.e2a52b14f0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/helpers/integration/crmFixtures.js +4 -0
  3. package/dist/helpers/integration/crmFixtures.js.map +2 -2
  4. package/dist/modules/attachments/api/route.js +2 -0
  5. package/dist/modules/attachments/api/route.js.map +2 -2
  6. package/dist/modules/attachments/lib/access.js +18 -0
  7. package/dist/modules/attachments/lib/access.js.map +2 -2
  8. package/dist/modules/auth/services/rbacService.js +3 -2
  9. package/dist/modules/auth/services/rbacService.js.map +2 -2
  10. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Diagnostics.js +0 -3
  11. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Diagnostics.js.map +2 -2
  12. package/dist/modules/customers/api/deals/route.js +43 -2
  13. package/dist/modules/customers/api/deals/route.js.map +2 -2
  14. package/dist/modules/customers/api/deals/summary/route.js +402 -0
  15. package/dist/modules/customers/api/deals/summary/route.js.map +7 -0
  16. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealActivities.js +16 -5
  17. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealActivities.js.map +2 -2
  18. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealData.js +22 -5
  19. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealData.js.map +2 -2
  20. package/dist/modules/customers/backend/customers/deals/[id]/page.js +12 -2
  21. package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
  22. package/dist/modules/customers/backend/customers/deals/page.js +221 -56
  23. package/dist/modules/customers/backend/customers/deals/page.js.map +3 -3
  24. package/dist/modules/customers/backend/customers/deals/pipeline/page.js +1 -1
  25. package/dist/modules/customers/backend/customers/deals/pipeline/page.js.map +2 -2
  26. package/dist/modules/customers/cli.js +15 -9
  27. package/dist/modules/customers/cli.js.map +2 -2
  28. package/dist/modules/customers/components/DealsKpiStrip.js +282 -0
  29. package/dist/modules/customers/components/DealsKpiStrip.js.map +7 -0
  30. package/dist/modules/customers/components/detail/ConfirmDealLostDialog.js +0 -1
  31. package/dist/modules/customers/components/detail/ConfirmDealLostDialog.js.map +2 -2
  32. package/dist/modules/customers/components/detail/DealForm.js +100 -17
  33. package/dist/modules/customers/components/detail/DealForm.js.map +2 -2
  34. package/dist/modules/customers/components/detail/ScheduleActivityDialog.js +1 -2
  35. package/dist/modules/customers/components/detail/ScheduleActivityDialog.js.map +2 -2
  36. package/dist/modules/customers/components/kpi/PipelineStageBar.js +63 -0
  37. package/dist/modules/customers/components/kpi/PipelineStageBar.js.map +7 -0
  38. package/dist/modules/customers/lib/dealsMetrics.js +82 -0
  39. package/dist/modules/customers/lib/dealsMetrics.js.map +7 -0
  40. package/dist/modules/directory/subscribers/invalidateOrgScopeCache.js +2 -1
  41. package/dist/modules/directory/subscribers/invalidateOrgScopeCache.js.map +2 -2
  42. package/dist/modules/directory/utils/organizationScope.js +59 -27
  43. package/dist/modules/directory/utils/organizationScope.js.map +2 -2
  44. package/dist/modules/entities/api/entities.js +7 -0
  45. package/dist/modules/entities/api/entities.js.map +2 -2
  46. package/dist/modules/entities/api/records.js +26 -15
  47. package/dist/modules/entities/api/records.js.map +2 -2
  48. package/dist/modules/entities/backend/entities/user/[entityId]/records/[recordId]/page.js +14 -0
  49. package/dist/modules/entities/backend/entities/user/[entityId]/records/[recordId]/page.js.map +2 -2
  50. package/dist/modules/entities/backend/entities/user/[entityId]/records/create/page.js +14 -0
  51. package/dist/modules/entities/backend/entities/user/[entityId]/records/create/page.js.map +2 -2
  52. package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js +12 -0
  53. package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js.map +2 -2
  54. package/dist/modules/entities/components/useRecordsEntityGuard.js +30 -0
  55. package/dist/modules/entities/components/useRecordsEntityGuard.js.map +7 -0
  56. package/dist/modules/query_index/lib/engine.js +4 -2
  57. package/dist/modules/query_index/lib/engine.js.map +2 -2
  58. package/dist/modules/staff/api/team-members.js +9 -2
  59. package/dist/modules/staff/api/team-members.js.map +2 -2
  60. package/dist/modules/staff/api/timesheets/time-entries/[id]/timer-start/route.js +24 -1
  61. package/dist/modules/staff/api/timesheets/time-entries/[id]/timer-start/route.js.map +2 -2
  62. package/dist/modules/staff/backend/staff/team-members/[id]/page.js +11 -6
  63. package/dist/modules/staff/backend/staff/team-members/[id]/page.js.map +2 -2
  64. package/dist/modules/staff/commands/team-members.js +1 -1
  65. package/dist/modules/staff/commands/team-members.js.map +2 -2
  66. package/dist/modules/staff/components/TeamMemberForm.js +1 -1
  67. package/dist/modules/staff/components/TeamMemberForm.js.map +2 -2
  68. package/dist/modules/staff/lib/scheduleSwitch.js +23 -0
  69. package/dist/modules/staff/lib/scheduleSwitch.js.map +7 -0
  70. package/dist/modules/workflows/backend/definitions/create/page.js +1 -2
  71. package/dist/modules/workflows/backend/definitions/create/page.js.map +2 -2
  72. package/dist/modules/workflows/backend/definitions/visual-editor/page.js +1 -2
  73. package/dist/modules/workflows/backend/definitions/visual-editor/page.js.map +2 -2
  74. package/dist/modules/workflows/components/DefinitionTriggersEditor.js +1 -2
  75. package/dist/modules/workflows/components/DefinitionTriggersEditor.js.map +2 -2
  76. package/dist/modules/workflows/components/NodeEditDialog.js +4 -13
  77. package/dist/modules/workflows/components/NodeEditDialog.js.map +2 -2
  78. package/dist/modules/workflows/components/NodeEditDialogCrudForm.js +4 -13
  79. package/dist/modules/workflows/components/NodeEditDialogCrudForm.js.map +2 -2
  80. package/dist/modules/workflows/components/WorkflowGraphImpl.js +1 -4
  81. package/dist/modules/workflows/components/WorkflowGraphImpl.js.map +2 -2
  82. package/dist/modules/workflows/components/fields/FormFieldArrayEditor.js +2 -5
  83. package/dist/modules/workflows/components/fields/FormFieldArrayEditor.js.map +2 -2
  84. package/package.json +8 -8
  85. package/src/helpers/integration/crmFixtures.ts +21 -1
  86. package/src/modules/attachments/AGENTS.md +79 -0
  87. package/src/modules/attachments/api/route.ts +2 -0
  88. package/src/modules/attachments/lib/access.ts +36 -0
  89. package/src/modules/auth/services/rbacService.ts +11 -2
  90. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Diagnostics.tsx +0 -3
  91. package/src/modules/customers/api/deals/route.ts +51 -2
  92. package/src/modules/customers/api/deals/summary/route.ts +496 -0
  93. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealActivities.ts +28 -6
  94. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealData.ts +33 -6
  95. package/src/modules/customers/backend/customers/deals/[id]/page.tsx +17 -2
  96. package/src/modules/customers/backend/customers/deals/page.tsx +254 -66
  97. package/src/modules/customers/backend/customers/deals/pipeline/page.tsx +1 -2
  98. package/src/modules/customers/cli.ts +15 -15
  99. package/src/modules/customers/components/DealsKpiStrip.tsx +389 -0
  100. package/src/modules/customers/components/detail/ConfirmDealLostDialog.tsx +0 -1
  101. package/src/modules/customers/components/detail/DealForm.tsx +121 -19
  102. package/src/modules/customers/components/detail/ScheduleActivityDialog.tsx +1 -2
  103. package/src/modules/customers/components/kpi/PipelineStageBar.tsx +77 -0
  104. package/src/modules/customers/i18n/de.json +43 -0
  105. package/src/modules/customers/i18n/en.json +43 -0
  106. package/src/modules/customers/i18n/es.json +43 -0
  107. package/src/modules/customers/i18n/pl.json +43 -0
  108. package/src/modules/customers/lib/dealsMetrics.ts +159 -0
  109. package/src/modules/directory/subscribers/invalidateOrgScopeCache.ts +3 -1
  110. package/src/modules/directory/utils/organizationScope.ts +85 -30
  111. package/src/modules/entities/api/entities.ts +11 -0
  112. package/src/modules/entities/api/records.ts +46 -25
  113. package/src/modules/entities/backend/entities/user/[entityId]/records/[recordId]/page.tsx +15 -0
  114. package/src/modules/entities/backend/entities/user/[entityId]/records/create/page.tsx +15 -0
  115. package/src/modules/entities/backend/entities/user/[entityId]/records/page.tsx +23 -0
  116. package/src/modules/entities/components/useRecordsEntityGuard.ts +41 -0
  117. package/src/modules/entities/i18n/de.json +1 -0
  118. package/src/modules/entities/i18n/en.json +1 -0
  119. package/src/modules/entities/i18n/es.json +1 -0
  120. package/src/modules/entities/i18n/pl.json +1 -0
  121. package/src/modules/query_index/lib/engine.ts +11 -5
  122. package/src/modules/staff/api/team-members.ts +9 -2
  123. package/src/modules/staff/api/timesheets/time-entries/[id]/timer-start/route.ts +31 -1
  124. package/src/modules/staff/backend/staff/team-members/[id]/page.tsx +18 -8
  125. package/src/modules/staff/commands/team-members.ts +5 -2
  126. package/src/modules/staff/components/TeamMemberForm.tsx +4 -1
  127. package/src/modules/staff/i18n/de.json +1 -0
  128. package/src/modules/staff/i18n/en.json +1 -0
  129. package/src/modules/staff/i18n/es.json +1 -0
  130. package/src/modules/staff/i18n/pl.json +1 -0
  131. package/src/modules/staff/lib/scheduleSwitch.ts +46 -0
  132. package/src/modules/workflows/backend/definitions/create/page.tsx +1 -2
  133. package/src/modules/workflows/backend/definitions/visual-editor/page.tsx +1 -2
  134. package/src/modules/workflows/components/DefinitionTriggersEditor.tsx +1 -2
  135. package/src/modules/workflows/components/NodeEditDialog.tsx +1 -4
  136. package/src/modules/workflows/components/NodeEditDialogCrudForm.tsx +4 -7
  137. package/src/modules/workflows/components/WorkflowGraphImpl.tsx +1 -2
  138. package/src/modules/workflows/components/fields/FormFieldArrayEditor.tsx +2 -3
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/modules/workflows/backend/definitions/visual-editor/page.tsx"],
4
- "sourcesContent": ["'use client'\n\nimport { WorkflowGraph } from '../../../components/WorkflowGraph'\n// Conditional imports based on feature flag\nimport { NodeEditDialog } from '../../../components/NodeEditDialog'\nimport { EdgeEditDialog } from '../../../components/EdgeEditDialog'\nimport { NodeEditDialogCrudForm } from '../../../components/NodeEditDialogCrudForm'\nimport { EdgeEditDialogCrudForm } from '../../../components/EdgeEditDialogCrudForm'\nimport { Node, Edge, addEdge, Connection, applyNodeChanges, applyEdgeChanges, NodeChange, EdgeChange } from '@xyflow/react'\nimport { useState, useCallback, useEffect } from 'react'\nimport { useRouter, useSearchParams } from 'next/navigation'\nimport { graphToDefinition, definitionToGraph, validateWorkflowGraph, generateStepId, generateTransitionId, ValidationError } from '../../../lib/graph-utils'\nimport { performDeleteEdgeFlow, performDeleteNodeFlow } from '../../../lib/visual-editor-delete-flow'\nimport { workflowDefinitionDataSchema } from '../../../data/validators'\nimport { Page } from '@open-mercato/ui/backend/Page'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport { Textarea } from '@open-mercato/ui/primitives/textarea'\nimport { Label } from '@open-mercato/ui/primitives/label'\nimport { Switch } from '@open-mercato/ui/primitives/switch'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from '@open-mercato/ui/primitives/dialog'\nimport { TagsInput } from '@open-mercato/ui/backend/inputs/TagsInput'\nimport { LoadingMessage } from '@open-mercato/ui/backend/detail'\nimport { Alert, AlertTitle } from '@open-mercato/ui/primitives/alert'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { FormHeader } from '@open-mercato/ui/backend/forms'\nimport { apiCall, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { surfaceRecordConflict } from '@open-mercato/ui/backend/conflicts'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { CircleQuestionMark, Info, PanelTopClose, PanelTopOpen, Play, Save, Trash2 } from 'lucide-react'\nimport { NODE_TYPE_ICONS, NODE_TYPE_COLORS, NODE_TYPE_LABELS } from '../../../lib/node-type-icons'\nimport { DefinitionTriggersEditor } from '../../../components/DefinitionTriggersEditor'\nimport { MobileVisualEditor } from '../../../components/mobile/MobileVisualEditor'\nimport { useIsMobile } from '@open-mercato/ui/hooks/useIsMobile'\nimport type { WorkflowDefinitionTrigger } from '../../../data/entities'\nimport type { WorkflowMetadataState, WorkflowMetadataHandlers } from '../../../data/types'\nimport * as React from 'react'\n\n/**\n * VisualEditorPage - Visual workflow definition editor\n *\n * Layout:\n * - Page Header: Title, description, and action buttons (Save, Validate, Test)\n * - Workflow Metadata: Collapsible form for workflow details\n * - Page Body:\n * - Left sidebar: Step palette (click to add)\n * - Main canvas: ReactFlow graph editor\n * - Flash Messages: Top-right positioned validation messages\n * - Edit Dialogs: Modal dialogs for editing steps and transitions\n */\nexport default function VisualEditorPage() {\n const t = useT()\n const router = useRouter()\n const searchParams = useSearchParams()\n const definitionId = searchParams.get('id')\n const isMobile = useIsMobile()\n\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n\n const [isLoading, setIsLoading] = useState(!!definitionId)\n const [isSaving, setIsSaving] = useState(false)\n const [nodes, setNodes] = useState<Node[]>([])\n const [edges, setEdges] = useState<Edge[]>([])\n const [selectedNode, setSelectedNode] = useState<Node | null>(null)\n const [selectedEdge, setSelectedEdge] = useState<Edge | null>(null)\n const [showMetadata, setShowMetadata] = useState(true)\n const [isCompactViewport, setIsCompactViewport] = useState(false)\n\n // Auto-collapse metadata on compact viewports after hydration\n useEffect(() => {\n if (typeof window === 'undefined') return\n const mediaQuery = window.matchMedia('(max-width: 1279px)')\n const applyViewportMode = () => {\n const compact = mediaQuery.matches\n setIsCompactViewport(compact)\n setShowMetadata(!compact)\n }\n\n applyViewportMode()\n mediaQuery.addEventListener('change', applyViewportMode)\n\n return () => {\n mediaQuery.removeEventListener('change', applyViewportMode)\n }\n }, [])\n const [showNodeDialog, setShowNodeDialog] = useState(false)\n const [showEdgeDialog, setShowEdgeDialog] = useState(false)\n const [showClearConfirm, setShowClearConfirm] = useState(false)\n\n // Workflow metadata state\n const [workflowId, setWorkflowId] = useState('')\n const [workflowName, setWorkflowName] = useState('')\n const [description, setDescription] = useState('')\n const [version, setVersion] = useState(1)\n const [enabled, setEnabled] = useState(true)\n const [category, setCategory] = useState('')\n const [tags, setTags] = useState<string[]>([])\n const [icon, setIcon] = useState('')\n const [effectiveFrom, setEffectiveFrom] = useState('')\n const [effectiveTo, setEffectiveTo] = useState('')\n const [triggers, setTriggers] = useState<WorkflowDefinitionTrigger[]>([])\n const [source, setSource] = useState<'code' | 'code_override' | 'user' | null>(null)\n const [updatedAt, setUpdatedAt] = useState<string | null>(null)\n\n const isCodeOnly = source === 'code'\n const isCodeOverride = source === 'code_override'\n\n // Load existing definition if ID is provided\n useEffect(() => {\n const loadDefinition = async () => {\n if (!definitionId) {\n setIsLoading(false)\n return\n }\n\n try {\n const result = await apiCall<{ data: any; error?: string }>(`/api/workflows/definitions/${definitionId}`)\n\n if (!result.ok) {\n flash(`Failed to load workflow: ${result.result?.error || 'Unknown error'}`, 'error')\n setIsLoading(false)\n return\n }\n\n const definition = result.result?.data\n\n // Populate metadata\n setWorkflowId(definition.workflowId)\n setWorkflowName(definition.workflowName || definition.definition.workflowName || '')\n setDescription(definition.description || definition.definition.description || '')\n setVersion(definition.version)\n setEnabled(definition.enabled)\n setCategory(definition.metadata?.category || '')\n setTags(definition.metadata?.tags || [])\n setIcon(definition.metadata?.icon || '')\n setEffectiveFrom(definition.effectiveFrom || '')\n setEffectiveTo(definition.effectiveTo || '')\n\n // Convert definition to graph\n const graph = definitionToGraph(definition.definition)\n setNodes(graph.nodes)\n setEdges(graph.edges)\n\n // Load embedded triggers from definition\n setTriggers(definition.definition?.triggers || [])\n\n // Track source so the editor mirrors the non-visual edit page UX:\n // code \u2192 read-only with Customize button; code_override \u2192 editable\n // with Reset to code; user \u2192 editable, no banner.\n setSource((definition.source as 'code' | 'code_override' | 'user') ?? null)\n setUpdatedAt(typeof definition.updatedAt === 'string' ? definition.updatedAt : null)\n } catch (error) {\n console.error('Error loading workflow definition:', error)\n flash('Failed to load workflow definition', 'error')\n } finally {\n setIsLoading(false)\n }\n }\n\n loadDefinition()\n }, [definitionId])\n\n // Handle node changes from ReactFlow\n const handleNodesChange = useCallback((changes: NodeChange[]) => {\n if (isCodeOnly) return\n setNodes((nds) => applyNodeChanges(changes, nds))\n }, [isCodeOnly])\n\n // Handle edge changes from ReactFlow\n const handleEdgesChange = useCallback((changes: EdgeChange[]) => {\n if (isCodeOnly) return\n setEdges((eds) => applyEdgeChanges(changes, eds))\n }, [isCodeOnly])\n\n // Handle adding new node from palette\n const handleAddNode = useCallback((nodeType: string) => {\n if (isCodeOnly) return\n const newNode: Node = {\n id: generateStepId(nodeType),\n type: nodeType,\n position: {\n x: 250 + nodes.length * 50,\n y: 100 + nodes.length * 150,\n },\n data: {\n label: getDefaultLabel(nodeType),\n description: '',\n badge: getDefaultBadge(nodeType),\n status: 'pending',\n },\n }\n\n setNodes((nds) => [...nds, newNode])\n }, [nodes.length, isCodeOnly])\n\n // Handle node selection - open edit dialog (suppressed in read-only mode\n // so users can't open the node editor on a code-defined workflow).\n const handleNodeClick = useCallback((_event: React.MouseEvent, node: Node) => {\n if (isCodeOnly) return\n setSelectedNode(node)\n setSelectedEdge(null)\n setShowNodeDialog(true)\n }, [isCodeOnly])\n\n // Handle edge selection - open edit dialog\n const handleEdgeClick = useCallback((_event: React.MouseEvent, edge: Edge) => {\n if (isCodeOnly) return\n setSelectedEdge(edge)\n setSelectedNode(null)\n setShowEdgeDialog(true)\n }, [isCodeOnly])\n\n // Save node updates\n const handleSaveNode = useCallback((nodeId: string, updates: Partial<Node['data']>) => {\n setNodes((nds) =>\n nds.map((node) =>\n node.id === nodeId\n ? { ...node, data: { ...node.data, ...updates } }\n : node\n )\n )\n flash('Node updated successfully', 'success')\n }, [])\n\n // Save edge updates\n const handleSaveEdge = useCallback((edgeId: string, updates: Partial<Edge['data']>) => {\n setEdges((eds) =>\n eds.map((edge) =>\n edge.id === edgeId\n ? { ...edge, data: { ...edge.data, ...updates } }\n : edge\n )\n )\n flash('Transition updated successfully', 'success')\n }, [])\n\n // Delete edge\n const handleDeleteEdge = useCallback(async (edgeId: string) => {\n await performDeleteEdgeFlow(edgeId, {\n confirm,\n t,\n setShowEdgeDialog,\n setSelectedEdge,\n setEdges,\n notifyDeleted: () => flash('Transition deleted successfully', 'success'),\n })\n }, [confirm, t])\n\n // Delete node\n const handleDeleteNode = useCallback(async (nodeId: string) => {\n await performDeleteNodeFlow(nodeId, {\n nodes,\n confirm,\n t,\n setShowNodeDialog,\n setSelectedNode,\n setNodes,\n setEdges,\n notifyDeleted: () => flash('Step deleted successfully', 'success'),\n })\n }, [confirm, nodes, t])\n\n // Handle new connections\n const handleConnect = useCallback((connection: Connection) => {\n const newEdge: Edge = {\n id: generateTransitionId(connection.source!, connection.target!),\n source: connection.source!,\n target: connection.target!,\n type: 'smoothstep',\n data: {\n trigger: 'auto',\n preConditions: [],\n postConditions: [],\n activities: [],\n label: '',\n },\n }\n\n setEdges((eds) => addEdge(newEdge, eds))\n }, [])\n\n // Validate workflow\n const handleValidate = useCallback(() => {\n const graphErrors = validateWorkflowGraph(nodes, edges)\n const allErrors: ValidationError[] = [...graphErrors]\n\n // Run Zod schema validation\n try {\n const definitionData = graphToDefinition(nodes, edges, { includePositions: true })\n const result = workflowDefinitionDataSchema.safeParse(definitionData)\n\n if (!result.success) {\n // Convert Zod errors to validation errors\n result.error.issues.forEach((issue) => {\n allErrors.push({\n type: 'error',\n message: `Schema validation: ${issue.path.join('.')} - ${issue.message}`,\n })\n })\n }\n } catch (error) {\n allErrors.push({\n type: 'error',\n message: `Schema validation failed: ${error instanceof Error ? error.message : 'Unknown error'}`,\n })\n }\n\n if (allErrors.length === 0) {\n flash('Validation passed! Your workflow is valid and ready to save.', 'success')\n } else {\n // Show first error/warning message\n const firstError = allErrors[0]\n const errorCount = allErrors.length\n const message = errorCount > 1\n ? `${firstError.message} (and ${errorCount - 1} more ${errorCount === 2 ? 'issue' : 'issues'})`\n : firstError.message\n flash(message, firstError.type === 'error' ? 'error' : 'warning')\n }\n }, [nodes, edges])\n\n // Save workflow definition\n const handleSave = useCallback(async () => {\n // Validate required fields\n if (!workflowId || !workflowName) {\n flash('Workflow ID and Name are required fields', 'error')\n return\n }\n\n // Validate workflow structure\n const errors = validateWorkflowGraph(nodes, edges)\n const criticalErrors = errors.filter(e => e.type === 'error')\n if (criticalErrors.length > 0) {\n flash(`Cannot save: ${criticalErrors.length} validation error(s) found. Please fix them first.`, 'error')\n return\n }\n\n // Generate definition data and include triggers\n const graphDefinition = graphToDefinition(nodes, edges, { includePositions: true })\n const definitionData = {\n ...graphDefinition,\n triggers: triggers.length > 0 ? triggers : undefined,\n }\n\n // Run Zod schema validation before saving\n const schemaResult = workflowDefinitionDataSchema.safeParse(definitionData)\n if (!schemaResult.success) {\n const firstIssue = schemaResult.error.issues[0]\n flash(`Schema error: ${firstIssue.path.join('.')} - ${firstIssue.message}`, 'error')\n return\n }\n\n setIsSaving(true)\n\n try {\n\n const metadata: any = {}\n if (category) metadata.category = category\n if (tags.length > 0) metadata.tags = tags\n if (icon) metadata.icon = icon\n\n // Determine if creating new or updating existing\n const isUpdate = !!definitionId\n\n let result\n if (isUpdate) {\n // Update existing definition \u2014 send the full editable payload so metadata\n // edits (name, description, version, category, tags, icon, effective\n // dates) actually persist. Previously only `definition` + `enabled`\n // were sent, silently dropping every other field.\n result = await withScopedApiRequestHeaders(\n buildOptimisticLockHeader(updatedAt),\n () => apiCall<{ data: any; error?: string }>(`/api/workflows/definitions/${definitionId}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n workflowName,\n description: description || null,\n version,\n definition: definitionData,\n metadata: Object.keys(metadata).length > 0 ? metadata : null,\n enabled,\n effectiveFrom: effectiveFrom || null,\n effectiveTo: effectiveTo || null,\n }),\n }),\n )\n } else {\n // Create new definition\n result = await apiCall<{ data: any; error?: string }>('/api/workflows/definitions', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n workflowId,\n workflowName,\n description: description || null,\n version,\n definition: definitionData,\n metadata: Object.keys(metadata).length > 0 ? metadata : null,\n enabled,\n effectiveFrom: effectiveFrom || null,\n effectiveTo: effectiveTo || null,\n }),\n })\n }\n\n if (!result.ok) {\n const conflictError = Object.assign(new Error(t('workflows.messages.saveFailed', 'Failed to save')), {\n status: result.status,\n ...(result.result && typeof result.result === 'object' ? result.result : {}),\n })\n if (!surfaceRecordConflict(conflictError, t)) {\n flash(`Failed to save: ${result.result?.error || 'Unknown error'}`, 'error')\n }\n return\n }\n\n const savedDefinition = result.result?.data\n\n flash(`Workflow ${isUpdate ? 'updated' : 'created'} successfully!`, 'success')\n\n // Redirect to definition detail page after short delay\n setTimeout(() => {\n router.push(`/backend/definitions/${savedDefinition.id}`)\n }, 1500)\n\n } catch (error) {\n console.error('Error saving workflow definition:', error)\n flash('Failed to save workflow definition. Please try again.', 'error')\n } finally {\n setIsSaving(false)\n }\n }, [nodes, edges, workflowId, workflowName, description, version, enabled, category, tags, icon, effectiveFrom, effectiveTo, triggers, definitionId, updatedAt, router])\n\n // Customize a code-defined workflow \u2192 creates an override and reloads the\n // editor pointed at the new UUID. Mirrors the non-visual edit page button.\n const handleCustomize = useCallback(async () => {\n if (!definitionId) return\n setIsSaving(true)\n try {\n const result = await apiCall<{ data?: { id?: string }; error?: string }>(\n `/api/workflows/definitions/${definitionId}/customize`,\n { method: 'POST' },\n )\n if (!result.ok) {\n flash(result.result?.error || 'Failed to customize workflow', 'error')\n return\n }\n const newId = result.result?.data?.id\n if (!newId) return\n router.push(`/backend/definitions/visual-editor?id=${encodeURIComponent(newId)}`)\n router.refresh()\n } finally {\n setIsSaving(false)\n }\n }, [definitionId, router])\n\n // Reset a code-override back to its code definition. Mirrors the\n // non-visual edit page action, with the same confirm dialog.\n const handleResetToCode = useCallback(async () => {\n if (!definitionId) return\n const confirmed = await confirm({\n title: t('workflows.actions.resetToCode'),\n description: t('workflows.actions.resetConfirm'),\n confirmText: t('workflows.actions.resetToCode'),\n variant: 'destructive',\n })\n if (!confirmed) return\n\n setIsSaving(true)\n try {\n const result = await apiCall<{ data?: { id?: string }; error?: string }>(\n `/api/workflows/definitions/${definitionId}/reset-to-code`,\n { method: 'POST' },\n )\n if (!result.ok) {\n flash(result.result?.error || 'Failed to reset workflow', 'error')\n return\n }\n const codeId = result.result?.data?.id || (workflowId ? `code:${workflowId}` : null)\n if (!codeId) return\n router.push(`/backend/definitions/visual-editor?id=${encodeURIComponent(codeId)}`)\n router.refresh()\n } finally {\n setIsSaving(false)\n }\n }, [definitionId, workflowId, router, confirm, t])\n\n // Test workflow\n const handleTest = useCallback(() => {\n // First validate\n const errors = validateWorkflowGraph(nodes, edges)\n const criticalErrors = errors.filter((e) => e.type === 'error')\n if (criticalErrors.length > 0) {\n flash(`Cannot test: ${criticalErrors.length} validation error(s) found. Please fix them first.`, 'error')\n return\n }\n\n // TODO: Implement test logic (create instance, run first step)\n flash('Test functionality will be implemented next', 'info')\n }, [nodes, edges])\n\n // Load example workflow\n const handleLoadExample = useCallback(() => {\n // Set example metadata\n setWorkflowId('approval_workflow')\n setWorkflowName('Simple Approval Workflow')\n setDescription('A basic approval workflow for reviewing and approving requests')\n setVersion(1)\n setEnabled(true)\n setCategory('Approvals')\n setTags(['approval', 'review'])\n\n const exampleNodes: Node[] = [\n {\n id: 'start',\n type: 'start',\n position: { x: 250, y: 50 },\n data: {\n label: 'Start',\n description: 'Workflow begins',\n status: 'pending',\n badge: 'Start',\n },\n },\n {\n id: 'step1',\n type: 'userTask',\n position: { x: 250, y: 250 },\n data: {\n label: 'Review Request',\n description: 'User reviews the incoming request',\n status: 'pending',\n stepNumber: 1,\n badge: 'User Task',\n assignedToRoles: ['Reviewer'],\n },\n },\n {\n id: 'end',\n type: 'end',\n position: { x: 250, y: 450 },\n data: {\n label: 'Complete',\n description: 'Workflow ends',\n status: 'pending',\n badge: 'End',\n },\n },\n ]\n\n const exampleEdges: Edge[] = [\n {\n id: 'e-start-step1',\n source: 'start',\n target: 'step1',\n type: 'smoothstep',\n data: {\n trigger: 'auto',\n preConditions: [],\n postConditions: [],\n activities: [],\n },\n },\n {\n id: 'e-step1-end',\n source: 'step1',\n target: 'end',\n type: 'smoothstep',\n data: {\n trigger: 'auto',\n preConditions: [],\n postConditions: [],\n activities: [],\n },\n },\n ]\n\n setNodes(exampleNodes)\n setEdges(exampleEdges)\n flash('Example workflow loaded', 'success')\n }, [])\n\n // Clear canvas\n const handleClear = useCallback(() => {\n if (nodes.length > 0 || edges.length > 0 || workflowId || workflowName) {\n setShowClearConfirm(true)\n }\n }, [nodes.length, edges.length, workflowId, workflowName])\n\n // Confirm clear action\n const confirmClear = useCallback(() => {\n setNodes([])\n setEdges([])\n setWorkflowId('')\n setWorkflowName('')\n setDescription('')\n setVersion(1)\n setEnabled(true)\n setCategory('')\n setTags([])\n setIcon('')\n setEffectiveFrom('')\n setEffectiveTo('')\n setTriggers([])\n setShowClearConfirm(false)\n flash('Canvas cleared', 'success')\n }, [])\n\n // Show loading spinner while loading definition\n if (isLoading) {\n return (\n <Page className=\"flex items-center justify-center min-h-[50vh]\">\n <LoadingMessage label=\"Loading workflow definition...\" />\n </Page>\n )\n }\n\n const metadata: WorkflowMetadataState = {\n workflowId, workflowName, description, version,\n enabled, category, tags, icon,\n effectiveFrom, effectiveTo, triggers,\n }\n\n const metadataHandlers: WorkflowMetadataHandlers = {\n setWorkflowId, setWorkflowName, setDescription, setVersion,\n setEnabled, setCategory, setTags, setIcon,\n setEffectiveFrom, setEffectiveTo, setTriggers,\n }\n\n const sharedDialogs = (\n <>\n {process.env.NEXT_PUBLIC_WORKFLOW_CRUDFORM_ENABLED === 'true' ? (\n <NodeEditDialogCrudForm node={selectedNode} isOpen={showNodeDialog} onClose={() => setShowNodeDialog(false)} onSave={handleSaveNode} onDelete={handleDeleteNode} />\n ) : (\n <NodeEditDialog node={selectedNode} isOpen={showNodeDialog} onClose={() => setShowNodeDialog(false)} onSave={handleSaveNode} onDelete={handleDeleteNode} />\n )}\n {process.env.NEXT_PUBLIC_WORKFLOW_CRUDFORM_ENABLED === 'true' ? (\n <EdgeEditDialogCrudForm edge={selectedEdge} isOpen={showEdgeDialog} onClose={() => setShowEdgeDialog(false)} onSave={handleSaveEdge} onDelete={handleDeleteEdge} />\n ) : (\n <EdgeEditDialog edge={selectedEdge} isOpen={showEdgeDialog} onClose={() => setShowEdgeDialog(false)} onSave={handleSaveEdge} onDelete={handleDeleteEdge} />\n )}\n <Dialog open={showClearConfirm} onOpenChange={setShowClearConfirm}>\n <DialogContent className=\"sm:max-w-md\">\n <DialogHeader>\n <DialogTitle>{t('workflows.visualEditor.clearTitle')}</DialogTitle>\n <DialogDescription>{t('workflows.visualEditor.clearDescription')}</DialogDescription>\n </DialogHeader>\n <DialogFooter>\n <Button variant=\"outline\" onClick={() => setShowClearConfirm(false)}>{t('common.cancel', 'Cancel')}</Button>\n <Button variant=\"destructive\" onClick={confirmClear}>{t('common.clear', 'Clear')}</Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </>\n )\n\n if (isMobile) {\n return (\n <Page className=\"flex h-[100svh] flex-col space-y-0 overflow-hidden\">\n <MobileVisualEditor\n definitionId={definitionId}\n isSaving={isSaving}\n nodes={nodes}\n edges={edges}\n onNodesChange={handleNodesChange}\n onEdgesChange={handleEdgesChange}\n onNodeClick={handleNodeClick}\n onEdgeClick={handleEdgeClick}\n onConnect={handleConnect}\n onAddNode={handleAddNode}\n onSave={handleSave}\n onValidate={handleValidate}\n onTest={handleTest}\n onLoadExample={handleLoadExample}\n onClear={handleClear}\n metadata={metadata}\n metadataHandlers={metadataHandlers}\n />\n {sharedDialogs}\n {ConfirmDialogElement}\n </Page>\n )\n }\n\n return (\n <Page className=\"space-y-0 overflow-x-hidden\">\n {/* Page Header */}\n <div className=\"shrink-0 border-b border-border bg-background px-3 py-2 md:px-6 md:py-3\">\n <FormHeader\n mode=\"detail\"\n backHref=\"/backend/definitions\"\n backLabel={t('workflows.definitions.backToList', 'Back to definitions')}\n title={definitionId ? (workflowName || t('workflows.definitions.singular')) : t('workflows.backend.definitions.visual_editor.title')}\n subtitle={definitionId\n ? t('workflows.definitions.detail.summary', 'Editing workflow definition')\n : t('workflows.definitions.create.summary', 'Create and edit workflow definitions visually with a drag-and-drop interface')\n }\n actionsContent={\n <div className=\"flex flex-wrap items-center justify-end gap-1 md:gap-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => setShowMetadata(!showMetadata)}\n disabled={isSaving}\n className=\"h-8 px-2 text-xs\"\n aria-label={showMetadata ? t('workflows.visualEditor.hideMetadata') : t('workflows.visualEditor.showMetadata')}\n >\n {showMetadata ? <PanelTopClose className=\"mr-1.5 h-4 w-4\" /> : <PanelTopOpen className=\"mr-1.5 h-4 w-4\" />}\n {showMetadata ? t('workflows.visualEditor.hideMetadata') : t('workflows.visualEditor.showMetadata')}\n </Button>\n {!isCodeOnly && (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleLoadExample}\n disabled={isSaving}\n className=\"h-8 text-xs\"\n >\n {t('workflows.visualEditor.loadExample')}\n </Button>\n )}\n {!isCodeOnly && (\n <Button\n variant=\"destructive\"\n size=\"sm\"\n onClick={handleClear}\n disabled={isSaving}\n className=\"h-8 px-2 text-xs\"\n aria-label={t('workflows.visualEditor.clear')}\n >\n <Trash2 className=\"mr-1.5 h-4 w-4\" />\n {t('workflows.visualEditor.clear')}\n </Button>\n )}\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleValidate}\n disabled={isSaving}\n className=\"h-8 px-2 text-xs\"\n aria-label={t('workflows.visualEditor.validate')}\n >\n <CircleQuestionMark className=\"mr-1.5 h-4 w-4\" />\n {t('workflows.visualEditor.validate')}\n </Button>\n {!isCodeOnly && (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleTest}\n disabled={isSaving}\n className=\"h-8 text-xs\"\n >\n <Play className=\"mr-1.5 h-4 w-4\" />\n {t('workflows.visualEditor.runTest')}\n </Button>\n )}\n {isCodeOverride && (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleResetToCode}\n disabled={isSaving}\n className=\"h-8 text-xs\"\n >\n {t('workflows.actions.resetToCode')}\n </Button>\n )}\n {isCodeOnly ? (\n <Button\n size=\"sm\"\n onClick={handleCustomize}\n disabled={isSaving}\n className=\"h-8 px-2 text-xs md:px-3\"\n >\n {t('workflows.actions.customize')}\n </Button>\n ) : (\n <Button\n size=\"sm\"\n onClick={handleSave}\n disabled={isSaving}\n className=\"h-8 px-2 text-xs md:px-3\"\n aria-label={isSaving ? t('workflows.mobile.saving') : definitionId ? t('workflows.common.update') : t('workflows.common.save')}\n >\n <Save className=\"mr-1.5 h-4 w-4\" />\n {isSaving ? t('workflows.mobile.saving') : definitionId ? t('workflows.common.update') : t('workflows.common.save')}\n </Button>\n )}\n </div>\n }\n />\n </div>\n\n {/* Source banner (code-defined / customized) */}\n {(isCodeOnly || isCodeOverride) && (\n <div className=\"shrink-0 border-b border-border bg-background px-3 py-2 md:px-6 md:py-3\">\n {isCodeOnly && (\n <Alert variant=\"info\">\n <AlertTitle>{t('workflows.source.code.readonlyBanner')}</AlertTitle>\n </Alert>\n )}\n {isCodeOverride && (\n <Alert variant=\"warning\">\n <AlertTitle>{t('workflows.source.code_override.banner')}</AlertTitle>\n </Alert>\n )}\n </div>\n )}\n\n {/* Workflow Metadata Form */}\n {showMetadata && (\n <div className={isCompactViewport\n ? 'shrink-0 border-b border-border bg-background px-3 py-2 max-h-[60svh] overflow-y-auto overscroll-contain md:px-6 md:py-3'\n : 'shrink-0 border-b border-border bg-background px-3 py-2 md:px-6 md:py-3'\n }>\n <fieldset disabled={isCodeOnly} className=\"rounded-lg border bg-card p-3 disabled:opacity-70 md:p-4\">\n <h2 className=\"mb-3 text-xs font-semibold uppercase text-muted-foreground\">{t('workflows.visualEditor.workflowMetadata')}</h2>\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3 md:gap-4\">\n {/* Workflow ID */}\n <div className=\"min-w-0 space-y-1\">\n <Label htmlFor=\"workflowId\" className=\"text-xs\">{t('workflows.form.workflowId')} *</Label>\n <Input\n id=\"workflowId\"\n value={workflowId}\n onChange={(e) => setWorkflowId(e.target.value)}\n placeholder=\"checkout_workflow\"\n disabled={!!definitionId}\n className=\"h-8 text-sm\"\n />\n {definitionId && <p className=\"text-overline text-muted-foreground\">{t('workflows.visualEditor.readOnly')}</p>}\n </div>\n\n {/* Workflow Name */}\n <div className=\"min-w-0 space-y-1\">\n <Label htmlFor=\"workflowName\" className=\"text-xs\">{t('workflows.form.workflowName')} *</Label>\n <Input\n id=\"workflowName\"\n value={workflowName}\n onChange={(e) => setWorkflowName(e.target.value)}\n placeholder=\"Checkout Process\"\n className=\"h-8 text-sm\"\n />\n </div>\n\n {/* Category */}\n <div className=\"min-w-0 space-y-1\">\n <Label htmlFor=\"category\" className=\"text-xs\">{t('workflows.form.category')}</Label>\n <Input\n id=\"category\"\n value={category}\n onChange={(e) => setCategory(e.target.value)}\n placeholder=\"E-Commerce\"\n className=\"h-8 text-sm\"\n />\n </div>\n\n {/* Description */}\n <div className=\"min-w-0 space-y-1 sm:col-span-2 lg:col-span-3\">\n <Label htmlFor=\"description\" className=\"text-xs\">{t('workflows.form.description')}</Label>\n <Textarea\n id=\"description\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder={t('workflows.form.placeholders.description')}\n rows={2}\n className=\"min-h-[60px] text-sm\"\n />\n </div>\n\n {/* Version */}\n <div className=\"min-w-0 space-y-1\">\n <Label htmlFor=\"version\" className=\"text-xs\">{t('workflows.form.version')} *</Label>\n <Input\n id=\"version\"\n type=\"number\"\n value={version}\n onChange={(e) => setVersion(parseInt(e.target.value) || 1)}\n min={1}\n disabled={!!definitionId}\n className=\"h-8 text-sm\"\n />\n </div>\n\n {/* Enabled */}\n <div className=\"min-w-0 space-y-1\">\n <Label className=\"text-xs\">{t('common.enabled', 'Enabled')}</Label>\n <div className=\"flex h-8 items-center gap-2\">\n <Switch\n id=\"enabled\"\n checked={enabled}\n onCheckedChange={setEnabled}\n />\n <Label htmlFor=\"enabled\" className=\"cursor-pointer text-xs font-normal\">\n {enabled ? t('common.on', 'On') : t('common.off', 'Off')}\n </Label>\n </div>\n </div>\n\n {/* Tags */}\n <div className=\"min-w-0 space-y-1\">\n <Label className=\"text-xs\">{t('workflows.form.tags')}</Label>\n <TagsInput\n value={tags}\n onChange={setTags}\n placeholder={t('workflows.form.placeholders.tags')}\n />\n </div>\n\n {/* Icon */}\n <div className=\"min-w-0 space-y-1\">\n <Label htmlFor=\"icon\" className=\"text-xs\">{t('workflows.form.icon')}</Label>\n <Input\n id=\"icon\"\n value={icon}\n onChange={(e) => setIcon(e.target.value)}\n placeholder=\"ShoppingCart\"\n className=\"h-8 text-sm\"\n />\n </div>\n\n <div className=\"min-w-0 space-y-1\">\n <Label htmlFor=\"effectiveFrom\" className=\"text-xs\">{t('workflows.form.effectiveFrom')}</Label>\n <Input\n id=\"effectiveFrom\"\n type=\"date\"\n value={effectiveFrom}\n onChange={(e) => setEffectiveFrom(e.target.value)}\n className=\"h-8 text-sm\"\n />\n </div>\n\n <div className=\"min-w-0 space-y-1\">\n <Label htmlFor=\"effectiveTo\" className=\"text-xs\">{t('workflows.form.effectiveTo')}</Label>\n <Input\n id=\"effectiveTo\"\n type=\"date\"\n value={effectiveTo}\n onChange={(e) => setEffectiveTo(e.target.value)}\n className=\"h-8 text-sm\"\n />\n </div>\n </div>\n </fieldset>\n\n {/* Event Triggers \u2014 also locked when the workflow is code-defined */}\n <fieldset disabled={isCodeOnly} className=\"mt-3 disabled:opacity-70\">\n <DefinitionTriggersEditor\n value={triggers}\n onChange={setTriggers}\n />\n </fieldset>\n </div>\n )}\n\n {/* Main Content */}\n {isCompactViewport ? (\n <div className=\"px-3 py-3 md:px-6 md:py-4\">\n <div className=\"relative min-w-0\">\n <div className=\"h-[64svh] min-h-[360px] rounded-lg border bg-card\">\n <WorkflowGraph\n initialNodes={nodes}\n initialEdges={edges}\n onNodesChange={handleNodesChange}\n onEdgesChange={handleEdgesChange}\n onNodeClick={handleNodeClick}\n onEdgeClick={handleEdgeClick}\n onConnect={handleConnect}\n editable={!isCodeOnly}\n height=\"100%\"\n />\n </div>\n\n {nodes.length === 0 && (\n <div className=\"pointer-events-none absolute inset-0 flex items-center justify-center px-4\">\n <div className=\"text-center\">\n <h2 className=\"mb-2 text-lg font-semibold text-foreground\">{t('workflows.visualEditor.startBuilding')}</h2>\n <p className=\"mb-4 text-sm text-muted-foreground\">{t('workflows.visualEditor.tapToAddBelow')}</p>\n <button\n onClick={handleLoadExample}\n className=\"pointer-events-auto text-sm text-primary hover:underline\"\n >\n {t('workflows.visualEditor.loadExampleWorkflow')}\n </button>\n </div>\n </div>\n )}\n </div>\n\n {!isCodeOnly && (\n <div className=\"mt-3 rounded-lg border bg-card p-3\">\n <h2 className=\"mb-2 text-xs font-semibold uppercase text-muted-foreground\">{t('workflows.visualEditor.stepPalette')}</h2>\n <p className=\"mb-3 text-xs text-muted-foreground\">{t('workflows.visualEditor.tapToAdd')}</p>\n\n <div className=\"flex gap-2 overflow-x-auto pb-1\">\n {(['start', 'userTask', 'automated', 'waitForSignal', 'waitForTimer', 'subWorkflow', 'end'] as const).map((nodeType) => {\n const Icon = NODE_TYPE_ICONS[nodeType]\n return (\n <button\n key={nodeType}\n onClick={() => handleAddNode(nodeType)}\n className=\"flex shrink-0 items-center gap-1 rounded-md border bg-background px-2 py-1 text-xs hover:bg-muted active:bg-muted/50\"\n >\n <Icon className=\"h-3.5 w-3.5\" />\n <span>{NODE_TYPE_LABELS[nodeType].title}</span>\n </button>\n )\n })}\n </div>\n </div>\n )}\n </div>\n ) : (\n <div className=\"flex min-h-[72svh] min-w-0 flex-1 border-t border-border\">\n {/* Left Sidebar - Step Palette (hidden in read-only mode) */}\n {!isCodeOnly && (\n <div className=\"w-[24rem] shrink-0 overflow-y-auto border-r border-border bg-background p-6\">\n <div className=\"rounded-lg border bg-card p-4\">\n <h2 className=\"mb-2 text-sm font-semibold uppercase text-muted-foreground\">{t('workflows.visualEditor.stepPalette')}</h2>\n <p className=\"mb-4 text-xs text-muted-foreground\">\n {t('workflows.visualEditor.clickToAdd')}\n </p>\n\n <div className=\"space-y-3\">\n {/* START Step */}\n <button\n onClick={() => handleAddNode('start')}\n className=\"group relative w-full cursor-pointer rounded-xl border-2 border-border bg-background px-4 py-3 text-left transition-all hover:border-muted-foreground/30 hover:shadow-md\"\n >\n <div className={`absolute right-2 top-2 ${NODE_TYPE_COLORS.start} opacity-60 transition-opacity group-hover:opacity-100`}>\n {(() => {\n const Icon = NODE_TYPE_ICONS.start\n return <Icon className=\"h-4 w-4\" />\n })()}\n </div>\n <div className=\"text-sm font-semibold text-foreground\">{NODE_TYPE_LABELS.start.title}</div>\n <div className=\"mt-0.5 text-xs text-muted-foreground\">{NODE_TYPE_LABELS.start.description}</div>\n </button>\n\n {/* USER_TASK Step */}\n <button\n onClick={() => handleAddNode('userTask')}\n className=\"group relative w-full cursor-pointer rounded-xl border-2 border-border bg-background px-4 py-3 text-left transition-all hover:border-muted-foreground/30 hover:shadow-md\"\n >\n <div className={`absolute right-2 top-2 ${NODE_TYPE_COLORS.userTask} opacity-60 transition-opacity group-hover:opacity-100`}>\n {(() => {\n const Icon = NODE_TYPE_ICONS.userTask\n return <Icon className=\"h-4 w-4\" />\n })()}\n </div>\n <div className=\"text-sm font-semibold text-foreground\">{NODE_TYPE_LABELS.userTask.title}</div>\n <div className=\"mt-0.5 text-xs text-muted-foreground\">{NODE_TYPE_LABELS.userTask.description}</div>\n </button>\n\n {/* AUTOMATED Step */}\n <button\n onClick={() => handleAddNode('automated')}\n className=\"group relative w-full cursor-pointer rounded-xl border-2 border-border bg-background px-4 py-3 text-left transition-all hover:border-muted-foreground/30 hover:shadow-md\"\n >\n <div className={`absolute right-2 top-2 ${NODE_TYPE_COLORS.automated} opacity-60 transition-opacity group-hover:opacity-100`}>\n {(() => {\n const Icon = NODE_TYPE_ICONS.automated\n return <Icon className=\"h-4 w-4\" />\n })()}\n </div>\n <div className=\"text-sm font-semibold text-foreground\">{NODE_TYPE_LABELS.automated.title}</div>\n <div className=\"mt-0.5 text-xs text-muted-foreground\">{NODE_TYPE_LABELS.automated.description}</div>\n </button>\n\n {/* WAIT_FOR_SIGNAL Step */}\n <button\n onClick={() => handleAddNode('waitForSignal')}\n className=\"group relative w-full cursor-pointer rounded-xl border-2 border-border bg-background px-4 py-3 text-left transition-all hover:border-muted-foreground/30 hover:shadow-md\"\n >\n <div className={`absolute right-2 top-2 ${NODE_TYPE_COLORS.waitForSignal} opacity-60 transition-opacity group-hover:opacity-100`}>\n {(() => {\n const Icon = NODE_TYPE_ICONS.waitForSignal\n return <Icon className=\"h-4 w-4\" />\n })()}\n </div>\n <div className=\"text-sm font-semibold text-foreground\">{NODE_TYPE_LABELS.waitForSignal.title}</div>\n <div className=\"mt-0.5 text-xs text-muted-foreground\">{NODE_TYPE_LABELS.waitForSignal.description}</div>\n </button>\n\n {/* WAIT_FOR_TIMER Step */}\n <button\n onClick={() => handleAddNode('waitForTimer')}\n className=\"group relative w-full cursor-pointer rounded-xl border-2 border-border bg-background px-4 py-3 text-left transition-all hover:border-muted-foreground/30 hover:shadow-md\"\n >\n <div className={`absolute right-2 top-2 ${NODE_TYPE_COLORS.waitForTimer} opacity-60 transition-opacity group-hover:opacity-100`}>\n {(() => {\n const Icon = NODE_TYPE_ICONS.waitForTimer\n return <Icon className=\"h-4 w-4\" />\n })()}\n </div>\n <div className=\"text-sm font-semibold text-foreground\">{NODE_TYPE_LABELS.waitForTimer.title}</div>\n <div className=\"mt-0.5 text-xs text-muted-foreground\">{NODE_TYPE_LABELS.waitForTimer.description}</div>\n </button>\n\n {/* SUB_WORKFLOW Step */}\n <button\n onClick={() => handleAddNode('subWorkflow')}\n className=\"group relative w-full cursor-pointer rounded-xl border-2 border-border bg-background px-4 py-3 text-left transition-all hover:border-muted-foreground/30 hover:shadow-md\"\n >\n <div className={`absolute right-2 top-2 ${NODE_TYPE_COLORS.subWorkflow} opacity-60 transition-opacity group-hover:opacity-100`}>\n {(() => {\n const Icon = NODE_TYPE_ICONS.subWorkflow\n return <Icon className=\"h-4 w-4\" />\n })()}\n </div>\n <div className=\"text-sm font-semibold text-foreground\">{NODE_TYPE_LABELS.subWorkflow.title}</div>\n <div className=\"mt-0.5 text-xs text-muted-foreground\">{NODE_TYPE_LABELS.subWorkflow.description}</div>\n </button>\n\n {/* END Step */}\n <button\n onClick={() => handleAddNode('end')}\n className=\"group relative w-full cursor-pointer rounded-xl border-2 border-border bg-background px-4 py-3 text-left transition-all hover:border-muted-foreground/30 hover:shadow-md\"\n >\n <div className={`absolute right-2 top-2 ${NODE_TYPE_COLORS.end} opacity-60 transition-opacity group-hover:opacity-100`}>\n {(() => {\n const Icon = NODE_TYPE_ICONS.end\n return <Icon className=\"h-4 w-4\" />\n })()}\n </div>\n <div className=\"text-sm font-semibold text-foreground\">{NODE_TYPE_LABELS.end.title}</div>\n <div className=\"mt-0.5 text-xs text-muted-foreground\">{NODE_TYPE_LABELS.end.description}</div>\n </button>\n </div>\n\n {/* Instructions */}\n <Alert variant=\"info\" className=\"mt-6\">\n <Info className=\"size-4\" />\n <AlertTitle className=\"text-xs\">{t('workflows.visualEditor.howToUse', 'How to use:')}</AlertTitle>\n <div className=\"mt-2\">\n <ul className=\"list-inside list-disc space-y-1 text-xs\">\n <li>{t('workflows.visualEditor.hint.addSteps', 'Click step types to add them')}</li>\n <li>{t('workflows.visualEditor.hint.dragSteps', 'Drag steps to position them')}</li>\n <li>{t('workflows.visualEditor.hint.connectSteps', 'Connect steps by dragging from handles')}</li>\n <li>{t('workflows.visualEditor.hint.editSteps', 'Click steps and transitions to edit them')}</li>\n <li>{t('workflows.visualEditor.hint.validate', 'Validate before saving')}</li>\n </ul>\n </div>\n </Alert>\n </div>\n </div>\n )}\n\n {/* Main Canvas */}\n <div className=\"min-w-0 flex-1 p-6\">\n <div className=\"relative h-[72svh] min-h-[640px]\">\n <div className=\"h-full rounded-lg border bg-card\">\n <WorkflowGraph\n initialNodes={nodes}\n initialEdges={edges}\n onNodesChange={handleNodesChange}\n onEdgesChange={handleEdgesChange}\n onNodeClick={handleNodeClick}\n onEdgeClick={handleEdgeClick}\n onConnect={handleConnect}\n editable={!isCodeOnly}\n height=\"100%\"\n />\n </div>\n\n {/* Empty State */}\n {nodes.length === 0 && (\n <div className=\"pointer-events-none absolute inset-0 flex items-center justify-center px-4\">\n <div className=\"text-center\">\n <h2 className=\"mb-2 text-xl font-semibold text-foreground\">\n {t('workflows.visualEditor.startBuilding')}\n </h2>\n <p className=\"mb-4 text-muted-foreground\">\n {t('workflows.visualEditor.clickToAddFromPalette')}\n </p>\n <button\n onClick={handleLoadExample}\n className=\"pointer-events-auto text-sm text-primary hover:underline\"\n >\n {t('workflows.visualEditor.loadExampleWorkflow')}\n </button>\n </div>\n </div>\n )}\n </div>\n </div>\n </div>\n )}\n {sharedDialogs}\n {ConfirmDialogElement}\n </Page>\n )\n}\n\n// Helper functions\nfunction getDefaultLabel(nodeType: string): string {\n const labels: Record<string, string> = {\n start: 'Start',\n end: 'End',\n userTask: 'New User Task',\n automated: 'New Automated Task',\n decision: 'Decision Point',\n waitForSignal: 'Wait for Signal',\n waitForTimer: 'Wait for Timer',\n }\n return labels[nodeType] || 'New Step'\n}\n\nfunction getDefaultBadge(nodeType: string): string {\n const badges: Record<string, string> = {\n start: 'Start',\n end: 'End',\n userTask: 'User Task',\n automated: 'Automated',\n decision: 'Decision',\n waitForSignal: 'Wait for Signal',\n waitForTimer: 'Wait for Timer',\n }\n return badges[nodeType] || 'Task'\n}\n\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["'use client'\n\nimport { WorkflowGraph } from '../../../components/WorkflowGraph'\n// Conditional imports based on feature flag\nimport { NodeEditDialog } from '../../../components/NodeEditDialog'\nimport { EdgeEditDialog } from '../../../components/EdgeEditDialog'\nimport { NodeEditDialogCrudForm } from '../../../components/NodeEditDialogCrudForm'\nimport { EdgeEditDialogCrudForm } from '../../../components/EdgeEditDialogCrudForm'\nimport { Node, Edge, addEdge, Connection, applyNodeChanges, applyEdgeChanges, NodeChange, EdgeChange } from '@xyflow/react'\nimport { useState, useCallback, useEffect } from 'react'\nimport { useRouter, useSearchParams } from 'next/navigation'\nimport { graphToDefinition, definitionToGraph, validateWorkflowGraph, generateStepId, generateTransitionId, ValidationError } from '../../../lib/graph-utils'\nimport { performDeleteEdgeFlow, performDeleteNodeFlow } from '../../../lib/visual-editor-delete-flow'\nimport { workflowDefinitionDataSchema } from '../../../data/validators'\nimport { Page } from '@open-mercato/ui/backend/Page'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport { Textarea } from '@open-mercato/ui/primitives/textarea'\nimport { Label } from '@open-mercato/ui/primitives/label'\nimport { Switch } from '@open-mercato/ui/primitives/switch'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from '@open-mercato/ui/primitives/dialog'\nimport { TagsInput } from '@open-mercato/ui/backend/inputs/TagsInput'\nimport { LoadingMessage } from '@open-mercato/ui/backend/detail'\nimport { Alert, AlertTitle } from '@open-mercato/ui/primitives/alert'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { FormHeader } from '@open-mercato/ui/backend/forms'\nimport { apiCall, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { surfaceRecordConflict } from '@open-mercato/ui/backend/conflicts'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { CircleQuestionMark, PanelTopClose, PanelTopOpen, Play, Save, Trash2 } from 'lucide-react'\nimport { NODE_TYPE_ICONS, NODE_TYPE_COLORS, NODE_TYPE_LABELS } from '../../../lib/node-type-icons'\nimport { DefinitionTriggersEditor } from '../../../components/DefinitionTriggersEditor'\nimport { MobileVisualEditor } from '../../../components/mobile/MobileVisualEditor'\nimport { useIsMobile } from '@open-mercato/ui/hooks/useIsMobile'\nimport type { WorkflowDefinitionTrigger } from '../../../data/entities'\nimport type { WorkflowMetadataState, WorkflowMetadataHandlers } from '../../../data/types'\nimport * as React from 'react'\n\n/**\n * VisualEditorPage - Visual workflow definition editor\n *\n * Layout:\n * - Page Header: Title, description, and action buttons (Save, Validate, Test)\n * - Workflow Metadata: Collapsible form for workflow details\n * - Page Body:\n * - Left sidebar: Step palette (click to add)\n * - Main canvas: ReactFlow graph editor\n * - Flash Messages: Top-right positioned validation messages\n * - Edit Dialogs: Modal dialogs for editing steps and transitions\n */\nexport default function VisualEditorPage() {\n const t = useT()\n const router = useRouter()\n const searchParams = useSearchParams()\n const definitionId = searchParams.get('id')\n const isMobile = useIsMobile()\n\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n\n const [isLoading, setIsLoading] = useState(!!definitionId)\n const [isSaving, setIsSaving] = useState(false)\n const [nodes, setNodes] = useState<Node[]>([])\n const [edges, setEdges] = useState<Edge[]>([])\n const [selectedNode, setSelectedNode] = useState<Node | null>(null)\n const [selectedEdge, setSelectedEdge] = useState<Edge | null>(null)\n const [showMetadata, setShowMetadata] = useState(true)\n const [isCompactViewport, setIsCompactViewport] = useState(false)\n\n // Auto-collapse metadata on compact viewports after hydration\n useEffect(() => {\n if (typeof window === 'undefined') return\n const mediaQuery = window.matchMedia('(max-width: 1279px)')\n const applyViewportMode = () => {\n const compact = mediaQuery.matches\n setIsCompactViewport(compact)\n setShowMetadata(!compact)\n }\n\n applyViewportMode()\n mediaQuery.addEventListener('change', applyViewportMode)\n\n return () => {\n mediaQuery.removeEventListener('change', applyViewportMode)\n }\n }, [])\n const [showNodeDialog, setShowNodeDialog] = useState(false)\n const [showEdgeDialog, setShowEdgeDialog] = useState(false)\n const [showClearConfirm, setShowClearConfirm] = useState(false)\n\n // Workflow metadata state\n const [workflowId, setWorkflowId] = useState('')\n const [workflowName, setWorkflowName] = useState('')\n const [description, setDescription] = useState('')\n const [version, setVersion] = useState(1)\n const [enabled, setEnabled] = useState(true)\n const [category, setCategory] = useState('')\n const [tags, setTags] = useState<string[]>([])\n const [icon, setIcon] = useState('')\n const [effectiveFrom, setEffectiveFrom] = useState('')\n const [effectiveTo, setEffectiveTo] = useState('')\n const [triggers, setTriggers] = useState<WorkflowDefinitionTrigger[]>([])\n const [source, setSource] = useState<'code' | 'code_override' | 'user' | null>(null)\n const [updatedAt, setUpdatedAt] = useState<string | null>(null)\n\n const isCodeOnly = source === 'code'\n const isCodeOverride = source === 'code_override'\n\n // Load existing definition if ID is provided\n useEffect(() => {\n const loadDefinition = async () => {\n if (!definitionId) {\n setIsLoading(false)\n return\n }\n\n try {\n const result = await apiCall<{ data: any; error?: string }>(`/api/workflows/definitions/${definitionId}`)\n\n if (!result.ok) {\n flash(`Failed to load workflow: ${result.result?.error || 'Unknown error'}`, 'error')\n setIsLoading(false)\n return\n }\n\n const definition = result.result?.data\n\n // Populate metadata\n setWorkflowId(definition.workflowId)\n setWorkflowName(definition.workflowName || definition.definition.workflowName || '')\n setDescription(definition.description || definition.definition.description || '')\n setVersion(definition.version)\n setEnabled(definition.enabled)\n setCategory(definition.metadata?.category || '')\n setTags(definition.metadata?.tags || [])\n setIcon(definition.metadata?.icon || '')\n setEffectiveFrom(definition.effectiveFrom || '')\n setEffectiveTo(definition.effectiveTo || '')\n\n // Convert definition to graph\n const graph = definitionToGraph(definition.definition)\n setNodes(graph.nodes)\n setEdges(graph.edges)\n\n // Load embedded triggers from definition\n setTriggers(definition.definition?.triggers || [])\n\n // Track source so the editor mirrors the non-visual edit page UX:\n // code \u2192 read-only with Customize button; code_override \u2192 editable\n // with Reset to code; user \u2192 editable, no banner.\n setSource((definition.source as 'code' | 'code_override' | 'user') ?? null)\n setUpdatedAt(typeof definition.updatedAt === 'string' ? definition.updatedAt : null)\n } catch (error) {\n console.error('Error loading workflow definition:', error)\n flash('Failed to load workflow definition', 'error')\n } finally {\n setIsLoading(false)\n }\n }\n\n loadDefinition()\n }, [definitionId])\n\n // Handle node changes from ReactFlow\n const handleNodesChange = useCallback((changes: NodeChange[]) => {\n if (isCodeOnly) return\n setNodes((nds) => applyNodeChanges(changes, nds))\n }, [isCodeOnly])\n\n // Handle edge changes from ReactFlow\n const handleEdgesChange = useCallback((changes: EdgeChange[]) => {\n if (isCodeOnly) return\n setEdges((eds) => applyEdgeChanges(changes, eds))\n }, [isCodeOnly])\n\n // Handle adding new node from palette\n const handleAddNode = useCallback((nodeType: string) => {\n if (isCodeOnly) return\n const newNode: Node = {\n id: generateStepId(nodeType),\n type: nodeType,\n position: {\n x: 250 + nodes.length * 50,\n y: 100 + nodes.length * 150,\n },\n data: {\n label: getDefaultLabel(nodeType),\n description: '',\n badge: getDefaultBadge(nodeType),\n status: 'pending',\n },\n }\n\n setNodes((nds) => [...nds, newNode])\n }, [nodes.length, isCodeOnly])\n\n // Handle node selection - open edit dialog (suppressed in read-only mode\n // so users can't open the node editor on a code-defined workflow).\n const handleNodeClick = useCallback((_event: React.MouseEvent, node: Node) => {\n if (isCodeOnly) return\n setSelectedNode(node)\n setSelectedEdge(null)\n setShowNodeDialog(true)\n }, [isCodeOnly])\n\n // Handle edge selection - open edit dialog\n const handleEdgeClick = useCallback((_event: React.MouseEvent, edge: Edge) => {\n if (isCodeOnly) return\n setSelectedEdge(edge)\n setSelectedNode(null)\n setShowEdgeDialog(true)\n }, [isCodeOnly])\n\n // Save node updates\n const handleSaveNode = useCallback((nodeId: string, updates: Partial<Node['data']>) => {\n setNodes((nds) =>\n nds.map((node) =>\n node.id === nodeId\n ? { ...node, data: { ...node.data, ...updates } }\n : node\n )\n )\n flash('Node updated successfully', 'success')\n }, [])\n\n // Save edge updates\n const handleSaveEdge = useCallback((edgeId: string, updates: Partial<Edge['data']>) => {\n setEdges((eds) =>\n eds.map((edge) =>\n edge.id === edgeId\n ? { ...edge, data: { ...edge.data, ...updates } }\n : edge\n )\n )\n flash('Transition updated successfully', 'success')\n }, [])\n\n // Delete edge\n const handleDeleteEdge = useCallback(async (edgeId: string) => {\n await performDeleteEdgeFlow(edgeId, {\n confirm,\n t,\n setShowEdgeDialog,\n setSelectedEdge,\n setEdges,\n notifyDeleted: () => flash('Transition deleted successfully', 'success'),\n })\n }, [confirm, t])\n\n // Delete node\n const handleDeleteNode = useCallback(async (nodeId: string) => {\n await performDeleteNodeFlow(nodeId, {\n nodes,\n confirm,\n t,\n setShowNodeDialog,\n setSelectedNode,\n setNodes,\n setEdges,\n notifyDeleted: () => flash('Step deleted successfully', 'success'),\n })\n }, [confirm, nodes, t])\n\n // Handle new connections\n const handleConnect = useCallback((connection: Connection) => {\n const newEdge: Edge = {\n id: generateTransitionId(connection.source!, connection.target!),\n source: connection.source!,\n target: connection.target!,\n type: 'smoothstep',\n data: {\n trigger: 'auto',\n preConditions: [],\n postConditions: [],\n activities: [],\n label: '',\n },\n }\n\n setEdges((eds) => addEdge(newEdge, eds))\n }, [])\n\n // Validate workflow\n const handleValidate = useCallback(() => {\n const graphErrors = validateWorkflowGraph(nodes, edges)\n const allErrors: ValidationError[] = [...graphErrors]\n\n // Run Zod schema validation\n try {\n const definitionData = graphToDefinition(nodes, edges, { includePositions: true })\n const result = workflowDefinitionDataSchema.safeParse(definitionData)\n\n if (!result.success) {\n // Convert Zod errors to validation errors\n result.error.issues.forEach((issue) => {\n allErrors.push({\n type: 'error',\n message: `Schema validation: ${issue.path.join('.')} - ${issue.message}`,\n })\n })\n }\n } catch (error) {\n allErrors.push({\n type: 'error',\n message: `Schema validation failed: ${error instanceof Error ? error.message : 'Unknown error'}`,\n })\n }\n\n if (allErrors.length === 0) {\n flash('Validation passed! Your workflow is valid and ready to save.', 'success')\n } else {\n // Show first error/warning message\n const firstError = allErrors[0]\n const errorCount = allErrors.length\n const message = errorCount > 1\n ? `${firstError.message} (and ${errorCount - 1} more ${errorCount === 2 ? 'issue' : 'issues'})`\n : firstError.message\n flash(message, firstError.type === 'error' ? 'error' : 'warning')\n }\n }, [nodes, edges])\n\n // Save workflow definition\n const handleSave = useCallback(async () => {\n // Validate required fields\n if (!workflowId || !workflowName) {\n flash('Workflow ID and Name are required fields', 'error')\n return\n }\n\n // Validate workflow structure\n const errors = validateWorkflowGraph(nodes, edges)\n const criticalErrors = errors.filter(e => e.type === 'error')\n if (criticalErrors.length > 0) {\n flash(`Cannot save: ${criticalErrors.length} validation error(s) found. Please fix them first.`, 'error')\n return\n }\n\n // Generate definition data and include triggers\n const graphDefinition = graphToDefinition(nodes, edges, { includePositions: true })\n const definitionData = {\n ...graphDefinition,\n triggers: triggers.length > 0 ? triggers : undefined,\n }\n\n // Run Zod schema validation before saving\n const schemaResult = workflowDefinitionDataSchema.safeParse(definitionData)\n if (!schemaResult.success) {\n const firstIssue = schemaResult.error.issues[0]\n flash(`Schema error: ${firstIssue.path.join('.')} - ${firstIssue.message}`, 'error')\n return\n }\n\n setIsSaving(true)\n\n try {\n\n const metadata: any = {}\n if (category) metadata.category = category\n if (tags.length > 0) metadata.tags = tags\n if (icon) metadata.icon = icon\n\n // Determine if creating new or updating existing\n const isUpdate = !!definitionId\n\n let result\n if (isUpdate) {\n // Update existing definition \u2014 send the full editable payload so metadata\n // edits (name, description, version, category, tags, icon, effective\n // dates) actually persist. Previously only `definition` + `enabled`\n // were sent, silently dropping every other field.\n result = await withScopedApiRequestHeaders(\n buildOptimisticLockHeader(updatedAt),\n () => apiCall<{ data: any; error?: string }>(`/api/workflows/definitions/${definitionId}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n workflowName,\n description: description || null,\n version,\n definition: definitionData,\n metadata: Object.keys(metadata).length > 0 ? metadata : null,\n enabled,\n effectiveFrom: effectiveFrom || null,\n effectiveTo: effectiveTo || null,\n }),\n }),\n )\n } else {\n // Create new definition\n result = await apiCall<{ data: any; error?: string }>('/api/workflows/definitions', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n workflowId,\n workflowName,\n description: description || null,\n version,\n definition: definitionData,\n metadata: Object.keys(metadata).length > 0 ? metadata : null,\n enabled,\n effectiveFrom: effectiveFrom || null,\n effectiveTo: effectiveTo || null,\n }),\n })\n }\n\n if (!result.ok) {\n const conflictError = Object.assign(new Error(t('workflows.messages.saveFailed', 'Failed to save')), {\n status: result.status,\n ...(result.result && typeof result.result === 'object' ? result.result : {}),\n })\n if (!surfaceRecordConflict(conflictError, t)) {\n flash(`Failed to save: ${result.result?.error || 'Unknown error'}`, 'error')\n }\n return\n }\n\n const savedDefinition = result.result?.data\n\n flash(`Workflow ${isUpdate ? 'updated' : 'created'} successfully!`, 'success')\n\n // Redirect to definition detail page after short delay\n setTimeout(() => {\n router.push(`/backend/definitions/${savedDefinition.id}`)\n }, 1500)\n\n } catch (error) {\n console.error('Error saving workflow definition:', error)\n flash('Failed to save workflow definition. Please try again.', 'error')\n } finally {\n setIsSaving(false)\n }\n }, [nodes, edges, workflowId, workflowName, description, version, enabled, category, tags, icon, effectiveFrom, effectiveTo, triggers, definitionId, updatedAt, router])\n\n // Customize a code-defined workflow \u2192 creates an override and reloads the\n // editor pointed at the new UUID. Mirrors the non-visual edit page button.\n const handleCustomize = useCallback(async () => {\n if (!definitionId) return\n setIsSaving(true)\n try {\n const result = await apiCall<{ data?: { id?: string }; error?: string }>(\n `/api/workflows/definitions/${definitionId}/customize`,\n { method: 'POST' },\n )\n if (!result.ok) {\n flash(result.result?.error || 'Failed to customize workflow', 'error')\n return\n }\n const newId = result.result?.data?.id\n if (!newId) return\n router.push(`/backend/definitions/visual-editor?id=${encodeURIComponent(newId)}`)\n router.refresh()\n } finally {\n setIsSaving(false)\n }\n }, [definitionId, router])\n\n // Reset a code-override back to its code definition. Mirrors the\n // non-visual edit page action, with the same confirm dialog.\n const handleResetToCode = useCallback(async () => {\n if (!definitionId) return\n const confirmed = await confirm({\n title: t('workflows.actions.resetToCode'),\n description: t('workflows.actions.resetConfirm'),\n confirmText: t('workflows.actions.resetToCode'),\n variant: 'destructive',\n })\n if (!confirmed) return\n\n setIsSaving(true)\n try {\n const result = await apiCall<{ data?: { id?: string }; error?: string }>(\n `/api/workflows/definitions/${definitionId}/reset-to-code`,\n { method: 'POST' },\n )\n if (!result.ok) {\n flash(result.result?.error || 'Failed to reset workflow', 'error')\n return\n }\n const codeId = result.result?.data?.id || (workflowId ? `code:${workflowId}` : null)\n if (!codeId) return\n router.push(`/backend/definitions/visual-editor?id=${encodeURIComponent(codeId)}`)\n router.refresh()\n } finally {\n setIsSaving(false)\n }\n }, [definitionId, workflowId, router, confirm, t])\n\n // Test workflow\n const handleTest = useCallback(() => {\n // First validate\n const errors = validateWorkflowGraph(nodes, edges)\n const criticalErrors = errors.filter((e) => e.type === 'error')\n if (criticalErrors.length > 0) {\n flash(`Cannot test: ${criticalErrors.length} validation error(s) found. Please fix them first.`, 'error')\n return\n }\n\n // TODO: Implement test logic (create instance, run first step)\n flash('Test functionality will be implemented next', 'info')\n }, [nodes, edges])\n\n // Load example workflow\n const handleLoadExample = useCallback(() => {\n // Set example metadata\n setWorkflowId('approval_workflow')\n setWorkflowName('Simple Approval Workflow')\n setDescription('A basic approval workflow for reviewing and approving requests')\n setVersion(1)\n setEnabled(true)\n setCategory('Approvals')\n setTags(['approval', 'review'])\n\n const exampleNodes: Node[] = [\n {\n id: 'start',\n type: 'start',\n position: { x: 250, y: 50 },\n data: {\n label: 'Start',\n description: 'Workflow begins',\n status: 'pending',\n badge: 'Start',\n },\n },\n {\n id: 'step1',\n type: 'userTask',\n position: { x: 250, y: 250 },\n data: {\n label: 'Review Request',\n description: 'User reviews the incoming request',\n status: 'pending',\n stepNumber: 1,\n badge: 'User Task',\n assignedToRoles: ['Reviewer'],\n },\n },\n {\n id: 'end',\n type: 'end',\n position: { x: 250, y: 450 },\n data: {\n label: 'Complete',\n description: 'Workflow ends',\n status: 'pending',\n badge: 'End',\n },\n },\n ]\n\n const exampleEdges: Edge[] = [\n {\n id: 'e-start-step1',\n source: 'start',\n target: 'step1',\n type: 'smoothstep',\n data: {\n trigger: 'auto',\n preConditions: [],\n postConditions: [],\n activities: [],\n },\n },\n {\n id: 'e-step1-end',\n source: 'step1',\n target: 'end',\n type: 'smoothstep',\n data: {\n trigger: 'auto',\n preConditions: [],\n postConditions: [],\n activities: [],\n },\n },\n ]\n\n setNodes(exampleNodes)\n setEdges(exampleEdges)\n flash('Example workflow loaded', 'success')\n }, [])\n\n // Clear canvas\n const handleClear = useCallback(() => {\n if (nodes.length > 0 || edges.length > 0 || workflowId || workflowName) {\n setShowClearConfirm(true)\n }\n }, [nodes.length, edges.length, workflowId, workflowName])\n\n // Confirm clear action\n const confirmClear = useCallback(() => {\n setNodes([])\n setEdges([])\n setWorkflowId('')\n setWorkflowName('')\n setDescription('')\n setVersion(1)\n setEnabled(true)\n setCategory('')\n setTags([])\n setIcon('')\n setEffectiveFrom('')\n setEffectiveTo('')\n setTriggers([])\n setShowClearConfirm(false)\n flash('Canvas cleared', 'success')\n }, [])\n\n // Show loading spinner while loading definition\n if (isLoading) {\n return (\n <Page className=\"flex items-center justify-center min-h-[50vh]\">\n <LoadingMessage label=\"Loading workflow definition...\" />\n </Page>\n )\n }\n\n const metadata: WorkflowMetadataState = {\n workflowId, workflowName, description, version,\n enabled, category, tags, icon,\n effectiveFrom, effectiveTo, triggers,\n }\n\n const metadataHandlers: WorkflowMetadataHandlers = {\n setWorkflowId, setWorkflowName, setDescription, setVersion,\n setEnabled, setCategory, setTags, setIcon,\n setEffectiveFrom, setEffectiveTo, setTriggers,\n }\n\n const sharedDialogs = (\n <>\n {process.env.NEXT_PUBLIC_WORKFLOW_CRUDFORM_ENABLED === 'true' ? (\n <NodeEditDialogCrudForm node={selectedNode} isOpen={showNodeDialog} onClose={() => setShowNodeDialog(false)} onSave={handleSaveNode} onDelete={handleDeleteNode} />\n ) : (\n <NodeEditDialog node={selectedNode} isOpen={showNodeDialog} onClose={() => setShowNodeDialog(false)} onSave={handleSaveNode} onDelete={handleDeleteNode} />\n )}\n {process.env.NEXT_PUBLIC_WORKFLOW_CRUDFORM_ENABLED === 'true' ? (\n <EdgeEditDialogCrudForm edge={selectedEdge} isOpen={showEdgeDialog} onClose={() => setShowEdgeDialog(false)} onSave={handleSaveEdge} onDelete={handleDeleteEdge} />\n ) : (\n <EdgeEditDialog edge={selectedEdge} isOpen={showEdgeDialog} onClose={() => setShowEdgeDialog(false)} onSave={handleSaveEdge} onDelete={handleDeleteEdge} />\n )}\n <Dialog open={showClearConfirm} onOpenChange={setShowClearConfirm}>\n <DialogContent className=\"sm:max-w-md\">\n <DialogHeader>\n <DialogTitle>{t('workflows.visualEditor.clearTitle')}</DialogTitle>\n <DialogDescription>{t('workflows.visualEditor.clearDescription')}</DialogDescription>\n </DialogHeader>\n <DialogFooter>\n <Button variant=\"outline\" onClick={() => setShowClearConfirm(false)}>{t('common.cancel', 'Cancel')}</Button>\n <Button variant=\"destructive\" onClick={confirmClear}>{t('common.clear', 'Clear')}</Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </>\n )\n\n if (isMobile) {\n return (\n <Page className=\"flex h-[100svh] flex-col space-y-0 overflow-hidden\">\n <MobileVisualEditor\n definitionId={definitionId}\n isSaving={isSaving}\n nodes={nodes}\n edges={edges}\n onNodesChange={handleNodesChange}\n onEdgesChange={handleEdgesChange}\n onNodeClick={handleNodeClick}\n onEdgeClick={handleEdgeClick}\n onConnect={handleConnect}\n onAddNode={handleAddNode}\n onSave={handleSave}\n onValidate={handleValidate}\n onTest={handleTest}\n onLoadExample={handleLoadExample}\n onClear={handleClear}\n metadata={metadata}\n metadataHandlers={metadataHandlers}\n />\n {sharedDialogs}\n {ConfirmDialogElement}\n </Page>\n )\n }\n\n return (\n <Page className=\"space-y-0 overflow-x-hidden\">\n {/* Page Header */}\n <div className=\"shrink-0 border-b border-border bg-background px-3 py-2 md:px-6 md:py-3\">\n <FormHeader\n mode=\"detail\"\n backHref=\"/backend/definitions\"\n backLabel={t('workflows.definitions.backToList', 'Back to definitions')}\n title={definitionId ? (workflowName || t('workflows.definitions.singular')) : t('workflows.backend.definitions.visual_editor.title')}\n subtitle={definitionId\n ? t('workflows.definitions.detail.summary', 'Editing workflow definition')\n : t('workflows.definitions.create.summary', 'Create and edit workflow definitions visually with a drag-and-drop interface')\n }\n actionsContent={\n <div className=\"flex flex-wrap items-center justify-end gap-1 md:gap-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => setShowMetadata(!showMetadata)}\n disabled={isSaving}\n className=\"h-8 px-2 text-xs\"\n aria-label={showMetadata ? t('workflows.visualEditor.hideMetadata') : t('workflows.visualEditor.showMetadata')}\n >\n {showMetadata ? <PanelTopClose className=\"mr-1.5 h-4 w-4\" /> : <PanelTopOpen className=\"mr-1.5 h-4 w-4\" />}\n {showMetadata ? t('workflows.visualEditor.hideMetadata') : t('workflows.visualEditor.showMetadata')}\n </Button>\n {!isCodeOnly && (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleLoadExample}\n disabled={isSaving}\n className=\"h-8 text-xs\"\n >\n {t('workflows.visualEditor.loadExample')}\n </Button>\n )}\n {!isCodeOnly && (\n <Button\n variant=\"destructive\"\n size=\"sm\"\n onClick={handleClear}\n disabled={isSaving}\n className=\"h-8 px-2 text-xs\"\n aria-label={t('workflows.visualEditor.clear')}\n >\n <Trash2 className=\"mr-1.5 h-4 w-4\" />\n {t('workflows.visualEditor.clear')}\n </Button>\n )}\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleValidate}\n disabled={isSaving}\n className=\"h-8 px-2 text-xs\"\n aria-label={t('workflows.visualEditor.validate')}\n >\n <CircleQuestionMark className=\"mr-1.5 h-4 w-4\" />\n {t('workflows.visualEditor.validate')}\n </Button>\n {!isCodeOnly && (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleTest}\n disabled={isSaving}\n className=\"h-8 text-xs\"\n >\n <Play className=\"mr-1.5 h-4 w-4\" />\n {t('workflows.visualEditor.runTest')}\n </Button>\n )}\n {isCodeOverride && (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleResetToCode}\n disabled={isSaving}\n className=\"h-8 text-xs\"\n >\n {t('workflows.actions.resetToCode')}\n </Button>\n )}\n {isCodeOnly ? (\n <Button\n size=\"sm\"\n onClick={handleCustomize}\n disabled={isSaving}\n className=\"h-8 px-2 text-xs md:px-3\"\n >\n {t('workflows.actions.customize')}\n </Button>\n ) : (\n <Button\n size=\"sm\"\n onClick={handleSave}\n disabled={isSaving}\n className=\"h-8 px-2 text-xs md:px-3\"\n aria-label={isSaving ? t('workflows.mobile.saving') : definitionId ? t('workflows.common.update') : t('workflows.common.save')}\n >\n <Save className=\"mr-1.5 h-4 w-4\" />\n {isSaving ? t('workflows.mobile.saving') : definitionId ? t('workflows.common.update') : t('workflows.common.save')}\n </Button>\n )}\n </div>\n }\n />\n </div>\n\n {/* Source banner (code-defined / customized) */}\n {(isCodeOnly || isCodeOverride) && (\n <div className=\"shrink-0 border-b border-border bg-background px-3 py-2 md:px-6 md:py-3\">\n {isCodeOnly && (\n <Alert variant=\"info\">\n <AlertTitle>{t('workflows.source.code.readonlyBanner')}</AlertTitle>\n </Alert>\n )}\n {isCodeOverride && (\n <Alert variant=\"warning\">\n <AlertTitle>{t('workflows.source.code_override.banner')}</AlertTitle>\n </Alert>\n )}\n </div>\n )}\n\n {/* Workflow Metadata Form */}\n {showMetadata && (\n <div className={isCompactViewport\n ? 'shrink-0 border-b border-border bg-background px-3 py-2 max-h-[60svh] overflow-y-auto overscroll-contain md:px-6 md:py-3'\n : 'shrink-0 border-b border-border bg-background px-3 py-2 md:px-6 md:py-3'\n }>\n <fieldset disabled={isCodeOnly} className=\"rounded-lg border bg-card p-3 disabled:opacity-70 md:p-4\">\n <h2 className=\"mb-3 text-xs font-semibold uppercase text-muted-foreground\">{t('workflows.visualEditor.workflowMetadata')}</h2>\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3 md:gap-4\">\n {/* Workflow ID */}\n <div className=\"min-w-0 space-y-1\">\n <Label htmlFor=\"workflowId\" className=\"text-xs\">{t('workflows.form.workflowId')} *</Label>\n <Input\n id=\"workflowId\"\n value={workflowId}\n onChange={(e) => setWorkflowId(e.target.value)}\n placeholder=\"checkout_workflow\"\n disabled={!!definitionId}\n className=\"h-8 text-sm\"\n />\n {definitionId && <p className=\"text-overline text-muted-foreground\">{t('workflows.visualEditor.readOnly')}</p>}\n </div>\n\n {/* Workflow Name */}\n <div className=\"min-w-0 space-y-1\">\n <Label htmlFor=\"workflowName\" className=\"text-xs\">{t('workflows.form.workflowName')} *</Label>\n <Input\n id=\"workflowName\"\n value={workflowName}\n onChange={(e) => setWorkflowName(e.target.value)}\n placeholder=\"Checkout Process\"\n className=\"h-8 text-sm\"\n />\n </div>\n\n {/* Category */}\n <div className=\"min-w-0 space-y-1\">\n <Label htmlFor=\"category\" className=\"text-xs\">{t('workflows.form.category')}</Label>\n <Input\n id=\"category\"\n value={category}\n onChange={(e) => setCategory(e.target.value)}\n placeholder=\"E-Commerce\"\n className=\"h-8 text-sm\"\n />\n </div>\n\n {/* Description */}\n <div className=\"min-w-0 space-y-1 sm:col-span-2 lg:col-span-3\">\n <Label htmlFor=\"description\" className=\"text-xs\">{t('workflows.form.description')}</Label>\n <Textarea\n id=\"description\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder={t('workflows.form.placeholders.description')}\n rows={2}\n className=\"min-h-[60px] text-sm\"\n />\n </div>\n\n {/* Version */}\n <div className=\"min-w-0 space-y-1\">\n <Label htmlFor=\"version\" className=\"text-xs\">{t('workflows.form.version')} *</Label>\n <Input\n id=\"version\"\n type=\"number\"\n value={version}\n onChange={(e) => setVersion(parseInt(e.target.value) || 1)}\n min={1}\n disabled={!!definitionId}\n className=\"h-8 text-sm\"\n />\n </div>\n\n {/* Enabled */}\n <div className=\"min-w-0 space-y-1\">\n <Label className=\"text-xs\">{t('common.enabled', 'Enabled')}</Label>\n <div className=\"flex h-8 items-center gap-2\">\n <Switch\n id=\"enabled\"\n checked={enabled}\n onCheckedChange={setEnabled}\n />\n <Label htmlFor=\"enabled\" className=\"cursor-pointer text-xs font-normal\">\n {enabled ? t('common.on', 'On') : t('common.off', 'Off')}\n </Label>\n </div>\n </div>\n\n {/* Tags */}\n <div className=\"min-w-0 space-y-1\">\n <Label className=\"text-xs\">{t('workflows.form.tags')}</Label>\n <TagsInput\n value={tags}\n onChange={setTags}\n placeholder={t('workflows.form.placeholders.tags')}\n />\n </div>\n\n {/* Icon */}\n <div className=\"min-w-0 space-y-1\">\n <Label htmlFor=\"icon\" className=\"text-xs\">{t('workflows.form.icon')}</Label>\n <Input\n id=\"icon\"\n value={icon}\n onChange={(e) => setIcon(e.target.value)}\n placeholder=\"ShoppingCart\"\n className=\"h-8 text-sm\"\n />\n </div>\n\n <div className=\"min-w-0 space-y-1\">\n <Label htmlFor=\"effectiveFrom\" className=\"text-xs\">{t('workflows.form.effectiveFrom')}</Label>\n <Input\n id=\"effectiveFrom\"\n type=\"date\"\n value={effectiveFrom}\n onChange={(e) => setEffectiveFrom(e.target.value)}\n className=\"h-8 text-sm\"\n />\n </div>\n\n <div className=\"min-w-0 space-y-1\">\n <Label htmlFor=\"effectiveTo\" className=\"text-xs\">{t('workflows.form.effectiveTo')}</Label>\n <Input\n id=\"effectiveTo\"\n type=\"date\"\n value={effectiveTo}\n onChange={(e) => setEffectiveTo(e.target.value)}\n className=\"h-8 text-sm\"\n />\n </div>\n </div>\n </fieldset>\n\n {/* Event Triggers \u2014 also locked when the workflow is code-defined */}\n <fieldset disabled={isCodeOnly} className=\"mt-3 disabled:opacity-70\">\n <DefinitionTriggersEditor\n value={triggers}\n onChange={setTriggers}\n />\n </fieldset>\n </div>\n )}\n\n {/* Main Content */}\n {isCompactViewport ? (\n <div className=\"px-3 py-3 md:px-6 md:py-4\">\n <div className=\"relative min-w-0\">\n <div className=\"h-[64svh] min-h-[360px] rounded-lg border bg-card\">\n <WorkflowGraph\n initialNodes={nodes}\n initialEdges={edges}\n onNodesChange={handleNodesChange}\n onEdgesChange={handleEdgesChange}\n onNodeClick={handleNodeClick}\n onEdgeClick={handleEdgeClick}\n onConnect={handleConnect}\n editable={!isCodeOnly}\n height=\"100%\"\n />\n </div>\n\n {nodes.length === 0 && (\n <div className=\"pointer-events-none absolute inset-0 flex items-center justify-center px-4\">\n <div className=\"text-center\">\n <h2 className=\"mb-2 text-lg font-semibold text-foreground\">{t('workflows.visualEditor.startBuilding')}</h2>\n <p className=\"mb-4 text-sm text-muted-foreground\">{t('workflows.visualEditor.tapToAddBelow')}</p>\n <button\n onClick={handleLoadExample}\n className=\"pointer-events-auto text-sm text-primary hover:underline\"\n >\n {t('workflows.visualEditor.loadExampleWorkflow')}\n </button>\n </div>\n </div>\n )}\n </div>\n\n {!isCodeOnly && (\n <div className=\"mt-3 rounded-lg border bg-card p-3\">\n <h2 className=\"mb-2 text-xs font-semibold uppercase text-muted-foreground\">{t('workflows.visualEditor.stepPalette')}</h2>\n <p className=\"mb-3 text-xs text-muted-foreground\">{t('workflows.visualEditor.tapToAdd')}</p>\n\n <div className=\"flex gap-2 overflow-x-auto pb-1\">\n {(['start', 'userTask', 'automated', 'waitForSignal', 'waitForTimer', 'subWorkflow', 'end'] as const).map((nodeType) => {\n const Icon = NODE_TYPE_ICONS[nodeType]\n return (\n <button\n key={nodeType}\n onClick={() => handleAddNode(nodeType)}\n className=\"flex shrink-0 items-center gap-1 rounded-md border bg-background px-2 py-1 text-xs hover:bg-muted active:bg-muted/50\"\n >\n <Icon className=\"h-3.5 w-3.5\" />\n <span>{NODE_TYPE_LABELS[nodeType].title}</span>\n </button>\n )\n })}\n </div>\n </div>\n )}\n </div>\n ) : (\n <div className=\"flex min-h-[72svh] min-w-0 flex-1 border-t border-border\">\n {/* Left Sidebar - Step Palette (hidden in read-only mode) */}\n {!isCodeOnly && (\n <div className=\"w-[24rem] shrink-0 overflow-y-auto border-r border-border bg-background p-6\">\n <div className=\"rounded-lg border bg-card p-4\">\n <h2 className=\"mb-2 text-sm font-semibold uppercase text-muted-foreground\">{t('workflows.visualEditor.stepPalette')}</h2>\n <p className=\"mb-4 text-xs text-muted-foreground\">\n {t('workflows.visualEditor.clickToAdd')}\n </p>\n\n <div className=\"space-y-3\">\n {/* START Step */}\n <button\n onClick={() => handleAddNode('start')}\n className=\"group relative w-full cursor-pointer rounded-xl border-2 border-border bg-background px-4 py-3 text-left transition-all hover:border-muted-foreground/30 hover:shadow-md\"\n >\n <div className={`absolute right-2 top-2 ${NODE_TYPE_COLORS.start} opacity-60 transition-opacity group-hover:opacity-100`}>\n {(() => {\n const Icon = NODE_TYPE_ICONS.start\n return <Icon className=\"h-4 w-4\" />\n })()}\n </div>\n <div className=\"text-sm font-semibold text-foreground\">{NODE_TYPE_LABELS.start.title}</div>\n <div className=\"mt-0.5 text-xs text-muted-foreground\">{NODE_TYPE_LABELS.start.description}</div>\n </button>\n\n {/* USER_TASK Step */}\n <button\n onClick={() => handleAddNode('userTask')}\n className=\"group relative w-full cursor-pointer rounded-xl border-2 border-border bg-background px-4 py-3 text-left transition-all hover:border-muted-foreground/30 hover:shadow-md\"\n >\n <div className={`absolute right-2 top-2 ${NODE_TYPE_COLORS.userTask} opacity-60 transition-opacity group-hover:opacity-100`}>\n {(() => {\n const Icon = NODE_TYPE_ICONS.userTask\n return <Icon className=\"h-4 w-4\" />\n })()}\n </div>\n <div className=\"text-sm font-semibold text-foreground\">{NODE_TYPE_LABELS.userTask.title}</div>\n <div className=\"mt-0.5 text-xs text-muted-foreground\">{NODE_TYPE_LABELS.userTask.description}</div>\n </button>\n\n {/* AUTOMATED Step */}\n <button\n onClick={() => handleAddNode('automated')}\n className=\"group relative w-full cursor-pointer rounded-xl border-2 border-border bg-background px-4 py-3 text-left transition-all hover:border-muted-foreground/30 hover:shadow-md\"\n >\n <div className={`absolute right-2 top-2 ${NODE_TYPE_COLORS.automated} opacity-60 transition-opacity group-hover:opacity-100`}>\n {(() => {\n const Icon = NODE_TYPE_ICONS.automated\n return <Icon className=\"h-4 w-4\" />\n })()}\n </div>\n <div className=\"text-sm font-semibold text-foreground\">{NODE_TYPE_LABELS.automated.title}</div>\n <div className=\"mt-0.5 text-xs text-muted-foreground\">{NODE_TYPE_LABELS.automated.description}</div>\n </button>\n\n {/* WAIT_FOR_SIGNAL Step */}\n <button\n onClick={() => handleAddNode('waitForSignal')}\n className=\"group relative w-full cursor-pointer rounded-xl border-2 border-border bg-background px-4 py-3 text-left transition-all hover:border-muted-foreground/30 hover:shadow-md\"\n >\n <div className={`absolute right-2 top-2 ${NODE_TYPE_COLORS.waitForSignal} opacity-60 transition-opacity group-hover:opacity-100`}>\n {(() => {\n const Icon = NODE_TYPE_ICONS.waitForSignal\n return <Icon className=\"h-4 w-4\" />\n })()}\n </div>\n <div className=\"text-sm font-semibold text-foreground\">{NODE_TYPE_LABELS.waitForSignal.title}</div>\n <div className=\"mt-0.5 text-xs text-muted-foreground\">{NODE_TYPE_LABELS.waitForSignal.description}</div>\n </button>\n\n {/* WAIT_FOR_TIMER Step */}\n <button\n onClick={() => handleAddNode('waitForTimer')}\n className=\"group relative w-full cursor-pointer rounded-xl border-2 border-border bg-background px-4 py-3 text-left transition-all hover:border-muted-foreground/30 hover:shadow-md\"\n >\n <div className={`absolute right-2 top-2 ${NODE_TYPE_COLORS.waitForTimer} opacity-60 transition-opacity group-hover:opacity-100`}>\n {(() => {\n const Icon = NODE_TYPE_ICONS.waitForTimer\n return <Icon className=\"h-4 w-4\" />\n })()}\n </div>\n <div className=\"text-sm font-semibold text-foreground\">{NODE_TYPE_LABELS.waitForTimer.title}</div>\n <div className=\"mt-0.5 text-xs text-muted-foreground\">{NODE_TYPE_LABELS.waitForTimer.description}</div>\n </button>\n\n {/* SUB_WORKFLOW Step */}\n <button\n onClick={() => handleAddNode('subWorkflow')}\n className=\"group relative w-full cursor-pointer rounded-xl border-2 border-border bg-background px-4 py-3 text-left transition-all hover:border-muted-foreground/30 hover:shadow-md\"\n >\n <div className={`absolute right-2 top-2 ${NODE_TYPE_COLORS.subWorkflow} opacity-60 transition-opacity group-hover:opacity-100`}>\n {(() => {\n const Icon = NODE_TYPE_ICONS.subWorkflow\n return <Icon className=\"h-4 w-4\" />\n })()}\n </div>\n <div className=\"text-sm font-semibold text-foreground\">{NODE_TYPE_LABELS.subWorkflow.title}</div>\n <div className=\"mt-0.5 text-xs text-muted-foreground\">{NODE_TYPE_LABELS.subWorkflow.description}</div>\n </button>\n\n {/* END Step */}\n <button\n onClick={() => handleAddNode('end')}\n className=\"group relative w-full cursor-pointer rounded-xl border-2 border-border bg-background px-4 py-3 text-left transition-all hover:border-muted-foreground/30 hover:shadow-md\"\n >\n <div className={`absolute right-2 top-2 ${NODE_TYPE_COLORS.end} opacity-60 transition-opacity group-hover:opacity-100`}>\n {(() => {\n const Icon = NODE_TYPE_ICONS.end\n return <Icon className=\"h-4 w-4\" />\n })()}\n </div>\n <div className=\"text-sm font-semibold text-foreground\">{NODE_TYPE_LABELS.end.title}</div>\n <div className=\"mt-0.5 text-xs text-muted-foreground\">{NODE_TYPE_LABELS.end.description}</div>\n </button>\n </div>\n\n {/* Instructions */}\n <Alert variant=\"info\" className=\"mt-6\">\n <AlertTitle className=\"text-xs\">{t('workflows.visualEditor.howToUse', 'How to use:')}</AlertTitle>\n <div className=\"mt-2\">\n <ul className=\"list-inside list-disc space-y-1 text-xs\">\n <li>{t('workflows.visualEditor.hint.addSteps', 'Click step types to add them')}</li>\n <li>{t('workflows.visualEditor.hint.dragSteps', 'Drag steps to position them')}</li>\n <li>{t('workflows.visualEditor.hint.connectSteps', 'Connect steps by dragging from handles')}</li>\n <li>{t('workflows.visualEditor.hint.editSteps', 'Click steps and transitions to edit them')}</li>\n <li>{t('workflows.visualEditor.hint.validate', 'Validate before saving')}</li>\n </ul>\n </div>\n </Alert>\n </div>\n </div>\n )}\n\n {/* Main Canvas */}\n <div className=\"min-w-0 flex-1 p-6\">\n <div className=\"relative h-[72svh] min-h-[640px]\">\n <div className=\"h-full rounded-lg border bg-card\">\n <WorkflowGraph\n initialNodes={nodes}\n initialEdges={edges}\n onNodesChange={handleNodesChange}\n onEdgesChange={handleEdgesChange}\n onNodeClick={handleNodeClick}\n onEdgeClick={handleEdgeClick}\n onConnect={handleConnect}\n editable={!isCodeOnly}\n height=\"100%\"\n />\n </div>\n\n {/* Empty State */}\n {nodes.length === 0 && (\n <div className=\"pointer-events-none absolute inset-0 flex items-center justify-center px-4\">\n <div className=\"text-center\">\n <h2 className=\"mb-2 text-xl font-semibold text-foreground\">\n {t('workflows.visualEditor.startBuilding')}\n </h2>\n <p className=\"mb-4 text-muted-foreground\">\n {t('workflows.visualEditor.clickToAddFromPalette')}\n </p>\n <button\n onClick={handleLoadExample}\n className=\"pointer-events-auto text-sm text-primary hover:underline\"\n >\n {t('workflows.visualEditor.loadExampleWorkflow')}\n </button>\n </div>\n </div>\n )}\n </div>\n </div>\n </div>\n )}\n {sharedDialogs}\n {ConfirmDialogElement}\n </Page>\n )\n}\n\n// Helper functions\nfunction getDefaultLabel(nodeType: string): string {\n const labels: Record<string, string> = {\n start: 'Start',\n end: 'End',\n userTask: 'New User Task',\n automated: 'New Automated Task',\n decision: 'Decision Point',\n waitForSignal: 'Wait for Signal',\n waitForTimer: 'Wait for Timer',\n }\n return labels[nodeType] || 'New Step'\n}\n\nfunction getDefaultBadge(nodeType: string): string {\n const badges: Record<string, string> = {\n start: 'Start',\n end: 'End',\n userTask: 'User Task',\n automated: 'Automated',\n decision: 'Decision',\n waitForSignal: 'Wait for Signal',\n waitForTimer: 'Wait for Timer',\n }\n return badges[nodeType] || 'Task'\n}\n\n"],
5
+ "mappings": "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",
6
6
  "names": ["metadata"]
7
7
  }
@@ -25,7 +25,7 @@ import {
25
25
  import { Alert, AlertDescription, AlertTitle } from "@open-mercato/ui/primitives/alert";
26
26
  import { EventPatternInput } from "@open-mercato/ui/backend/inputs/EventPatternInput";
27
27
  import { useT } from "@open-mercato/shared/lib/i18n/context";
28
- import { Plus, Trash2, Edit2, Zap, Info, X } from "lucide-react";
28
+ import { Plus, Trash2, Edit2, Zap, X } from "lucide-react";
29
29
  const FILTER_OPERATORS = [
30
30
  { value: "eq", label: "Equals" },
31
31
  { value: "neq", label: "Not Equals" },
@@ -217,7 +217,6 @@ function DefinitionTriggersEditor({
217
217
  ] }),
218
218
  /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mb-4", children: t("workflows.triggers.description", "Configure events that automatically start this workflow. When a matching event occurs in the system, a new workflow instance will be created with the mapped context.") }),
219
219
  value.length === 0 ? /* @__PURE__ */ jsxs(Alert, { variant: "info", children: [
220
- /* @__PURE__ */ jsx(Info, { className: "w-4 h-4" }),
221
220
  /* @__PURE__ */ jsx(AlertTitle, { children: t("workflows.triggers.empty.title", "No triggers configured") }),
222
221
  /* @__PURE__ */ jsx(AlertDescription, { children: t("workflows.triggers.empty.description", 'Click "Add Trigger" to create an event trigger that automatically starts this workflow.') })
223
222
  ] }) : /* @__PURE__ */ jsx("div", { className: "space-y-2", children: value.map((trigger) => /* @__PURE__ */ jsxs(