"use client"; import { IconArrowRight, IconLogicBuffer } from "@tabler/icons-react"; import { ContextMenuItem, ContextMenuSeparator, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, } from "@kandev/ui/context-menu"; import { cn } from "@/lib/utils"; export type TaskMoveStep = { id: string; title: string; color?: string | null; events?: { on_enter?: Array<{ type: string; config?: Record }> }; }; export type TaskMoveWorkflow = { id: string; name: string; hidden?: boolean; }; type TaskMoveContextMenuItemsProps = { currentWorkflowId?: string | null; currentStepId?: string | null; workflows: TaskMoveWorkflow[]; stepsByWorkflowId: Record; disabled?: boolean; showSeparator?: boolean; onMoveToStep?: (stepId: string) => void; onSendToWorkflow?: (workflowId: string, stepId: string) => void; }; export function stepHasAutoStart(step: TaskMoveStep) { return step.events?.on_enter?.some((action) => action.type === "auto_start_agent") ?? false; } function StepMenuItem({ step, currentStepId, onSelect, }: { step: TaskMoveStep; currentStepId?: string | null; onSelect: (stepId: string) => void; }) { const isCurrent = step.id === currentStepId; const hasAutoStart = stepHasAutoStart(step); return ( { event.preventDefault(); if (!isCurrent) onSelect(step.id); }} > {step.title} {(isCurrent || hasAutoStart) && ( {isCurrent && Current} {hasAutoStart && ( Auto-start )} )} ); } function MoveToCurrentWorkflowSubmenu({ steps, currentStepId, disabled, onMoveToStep, }: { steps: TaskMoveStep[]; currentStepId?: string | null; disabled?: boolean; onMoveToStep?: (stepId: string) => void; }) { if (!onMoveToStep || steps.length <= 1) return null; return ( Move to {steps.map((step) => ( ))} ); } function WorkflowTargetItem({ workflow, steps, disabled, onSendToWorkflow, }: { workflow: TaskMoveWorkflow; steps: TaskMoveStep[]; disabled?: boolean; onSendToWorkflow?: (workflowId: string, stepId: string) => void; }) { if (steps.length === 0 || !onSendToWorkflow) { return ( {workflow.name} No steps ); } return ( {workflow.name} {steps.map((step) => ( onSendToWorkflow(workflow.id, stepId)} /> ))} ); } function SendToWorkflowSubmenu({ currentWorkflowId, workflows, stepsByWorkflowId, disabled, onSendToWorkflow, }: { currentWorkflowId?: string | null; workflows: TaskMoveWorkflow[]; stepsByWorkflowId: Record; disabled?: boolean; onSendToWorkflow?: (workflowId: string, stepId: string) => void; }) { const targets = workflows.filter((workflow) => workflow.id !== currentWorkflowId); if (!onSendToWorkflow || !currentWorkflowId || targets.length === 0) return null; return ( Send to workflow {targets.map((workflow) => ( ))} ); } export function TaskMoveContextMenuItems({ currentWorkflowId, currentStepId, workflows, stepsByWorkflowId, disabled, showSeparator = true, onMoveToStep, onSendToWorkflow, }: TaskMoveContextMenuItemsProps) { const visibleWorkflows = workflows.filter((workflow) => !workflow.hidden); const currentSteps = currentWorkflowId ? (stepsByWorkflowId[currentWorkflowId] ?? []) : []; const hasSameWorkflowMove = Boolean(onMoveToStep && currentSteps.length > 1); const hasCrossWorkflowMove = Boolean( onSendToWorkflow && currentWorkflowId && visibleWorkflows.some((workflow) => workflow.id !== currentWorkflowId), ); if (!hasSameWorkflowMove && !hasCrossWorkflowMove) return null; return ( <> {showSeparator && } ); }