Files
kandev/apps/web/components/step-capability-icons.tsx
T
João Salavisa 03d5f98cb6 feat(i18n): localize Settings → Workflows (#2201)
Co-authored-by: Kandev Agent <agent@kandev.dev>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-03 15:30:27 +02:00

115 lines
3.3 KiB
TypeScript

import type React from "react";
import type { Icon } from "@tabler/icons-react";
import { useTranslation } from "react-i18next";
import {
IconArrowRight,
IconClipboard,
IconDoorExit,
IconMessageForward,
IconRefresh,
IconRobot,
IconUserCog,
} from "@tabler/icons-react";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@kandev/ui/tooltip";
import type { KanbanStepEvents } from "@/lib/state/slices/kanban/types";
type StepCapabilityIconsProps = {
events?: KanbanStepEvents;
agentProfileId?: string;
className?: string;
fallback?: React.ReactNode;
};
const TRANSITION_TYPES = ["move_to_next", "move_to_previous", "move_to_step"];
type CapabilityDef = {
key: string;
icon: Icon;
/** Catalog key: `key` and the action `type`s it checks are wire values. */
tooltipKey: string;
check: (events: KanbanStepEvents) => boolean;
};
const CAPABILITIES: CapabilityDef[] = [
{
key: "onTurnStart",
icon: IconMessageForward,
tooltipKey: "workflows:onUserMessage",
check: (e) => e.on_turn_start?.some((a) => TRANSITION_TYPES.includes(a.type)) ?? false,
},
{
key: "autoStart",
icon: IconRobot,
tooltipKey: "workflows:autoStartAgent",
check: (e) => e.on_enter?.some((a) => a.type === "auto_start_agent") ?? false,
},
{
key: "planMode",
icon: IconClipboard,
tooltipKey: "workflows:planMode",
check: (e) => e.on_enter?.some((a) => a.type === "enable_plan_mode") ?? false,
},
{
key: "resetContext",
icon: IconRefresh,
tooltipKey: "workflows:resetAgentContext",
check: (e) => e.on_enter?.some((a) => a.type === "reset_agent_context") ?? false,
},
{
key: "transition",
icon: IconArrowRight,
tooltipKey: "workflows:autoTransition",
check: (e) => e.on_turn_complete?.some((a) => TRANSITION_TYPES.includes(a.type)) ?? false,
},
{
key: "onExit",
icon: IconDoorExit,
tooltipKey: "workflows:onExitActions",
check: (e) => (e.on_exit?.length ?? 0) > 0,
},
];
export function StepCapabilityIcons({
events,
agentProfileId,
className,
fallback,
}: StepCapabilityIconsProps) {
const { t } = useTranslation();
const defaultClassName = "flex items-center gap-1.5 text-muted-foreground";
const activeCapabilities = events ? CAPABILITIES.filter((cap) => cap.check(events)) : [];
const hasAgentProfile = Boolean(agentProfileId);
if (activeCapabilities.length === 0 && !hasAgentProfile) {
return fallback ? <div className={className ?? defaultClassName}>{fallback}</div> : null;
}
return (
<div className={className ?? defaultClassName}>
{hasAgentProfile && (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<IconUserCog className="h-3.5 w-3.5" />
</TooltipTrigger>
<TooltipContent>{t("workflows:customAgentProfile")}</TooltipContent>
</Tooltip>
</TooltipProvider>
)}
{activeCapabilities.map((cap) => {
const IconComponent = cap.icon;
return (
<TooltipProvider key={cap.key}>
<Tooltip>
<TooltipTrigger asChild>
<IconComponent className="h-3.5 w-3.5" />
</TooltipTrigger>
<TooltipContent>{t(cap.tooltipKey)}</TooltipContent>
</Tooltip>
</TooltipProvider>
);
})}
</div>
);
}