"use client"; import * as React from "react"; import { Actions, PanelActions, type PanelActionObjectOption, } from "@repo/ui"; import type { ToolcraftActionSchema, ToolcraftControlSchema, } from "../../../schema/types"; import { isToolcraftArtifactExportAction } from "../../../schema/artifact-export-actions"; export type ActionControlRunAction = ( action: ToolcraftActionSchema, options?: { trackFooterPending?: boolean }, ) => void; export type ActionControlRenderArgs = { control: ToolcraftControlSchema; id: string; name: string; runAction: ActionControlRunAction; }; function getPanelActionButtonVariant( variant: ToolcraftActionSchema["variant"], ): PanelActionObjectOption["variant"] { switch (variant) { case "destructive": case "ghost": case "link": case "outline": case "secondary": return variant; default: return "default"; } } function asActionSchemas( actions: readonly (ToolcraftActionSchema | string)[] | undefined, ): readonly ToolcraftActionSchema[] { return (actions ?? []).map((action) => typeof action === "string" ? { label: action, value: action, } : action, ); } function getActionLabel(action: ToolcraftActionSchema): string { return action.label ?? action.value; } function isExportPanelAction(action: ToolcraftActionSchema): boolean { if (isToolcraftArtifactExportAction(action)) { return true; } const label = getActionLabel(action); const value = action.value; return ( /\bexport\b/i.test(label) || /(?:^|[._:-])export(?:[._:-]|$)/i.test(value) || /^export(?:[._:-]|$)/i.test(value) ); } function getPanelActionIcon( action: ToolcraftActionSchema, ): PanelActionObjectOption["icon"] { return isExportPanelAction(action) ? "upload-simple" : action.icon; } export function renderActionControl({ control, id, name, runAction, }: ActionControlRenderArgs): React.ReactNode | null { switch (control.type) { case "actions": { const actions = asActionSchemas(control.actions); return ( ({ icon: action.icon, label: action.label, value: action.value, }))} key={id} name={name} onAction={(actionValue) => { const action = actions.find((item) => item.value === actionValue); if (action) { runAction(action); } }} showLabel={control.label !== false} /> ); } case "panelActions": { const actions = asActionSchemas(control.actions); return ( ({ icon: getPanelActionIcon(action), name: getActionLabel(action), value: action.value, variant: getPanelActionButtonVariant(action.variant), }))} key={id} onAction={(actionValue) => { const action = actions.find((item) => item.value === actionValue); if (action) { runAction(action, { trackFooterPending: true }); } }} /> ); } default: return null; } }