diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/tool-input/tool-input.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/tool-input/tool-input.tsx index 46228def69..8cea6fd0fe 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/tool-input/tool-input.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/tool-input/tool-input.tsx @@ -16,7 +16,7 @@ import { Switch, Tooltip, } from '@/components/emcn' -import { McpIcon } from '@/components/icons' +import { McpIcon, WorkflowIcon } from '@/components/icons' import { cn } from '@/lib/core/utils/cn' import { getIssueBadgeLabel, @@ -30,6 +30,7 @@ import { type OAuthProvider, type OAuthService, } from '@/lib/oauth' +import { useUserPermissionsContext } from '@/app/workspace/[workspaceId]/providers/workspace-permissions-provider' import { CheckboxList, Code, @@ -769,9 +770,10 @@ function WorkflowToolDeployBadge({ }) { const { isDeployed, needsRedeploy, isLoading, refetch } = useChildDeployment(workflowId) const [isDeploying, setIsDeploying] = useState(false) + const userPermissions = useUserPermissionsContext() const deployWorkflow = useCallback(async () => { - if (isDeploying || !workflowId) return + if (isDeploying || !workflowId || !userPermissions.canAdmin) return try { setIsDeploying(true) @@ -796,7 +798,7 @@ function WorkflowToolDeployBadge({ } finally { setIsDeploying(false) } - }, [isDeploying, workflowId, refetch, onDeploySuccess]) + }, [isDeploying, workflowId, refetch, onDeploySuccess, userPermissions.canAdmin]) if (isLoading || (isDeployed && !needsRedeploy)) { return null @@ -811,13 +813,13 @@ function WorkflowToolDeployBadge({ { e.stopPropagation() e.preventDefault() - if (!isDeploying) { + if (!isDeploying && userPermissions.canAdmin) { deployWorkflow() } }} @@ -826,7 +828,13 @@ function WorkflowToolDeployBadge({ - {!isDeployed ? 'Click to deploy' : 'Click to redeploy'} + + {!userPermissions.canAdmin + ? 'Admin permission required to deploy' + : !isDeployed + ? 'Click to deploy' + : 'Click to redeploy'} + ) @@ -933,6 +941,13 @@ export function ToolInput({ const forceRefreshMcpTools = useForceRefreshMcpTools() const openSettingsModal = useSettingsModalStore((state) => state.openModal) const mcpDataLoading = mcpLoading || mcpServersLoading + + // Fetch workflows for the Workflows section in the dropdown + const { data: workflowsList = [] } = useWorkflows(workspaceId, { syncRegistry: false }) + const availableWorkflows = useMemo( + () => workflowsList.filter((w) => w.id !== workflowId), + [workflowsList, workflowId] + ) const hasRefreshedRef = useRef(false) const hasMcpTools = selectedTools.some((tool) => tool.type === 'mcp') @@ -1735,6 +1750,36 @@ export function ToolInput({ }) } + // Workflows section - shows available workflows that can be executed as tools + if (availableWorkflows.length > 0) { + groups.push({ + section: 'Workflows', + items: availableWorkflows.map((workflow) => ({ + label: workflow.name, + value: `workflow-${workflow.id}`, + iconElement: createToolIcon('#6366F1', WorkflowIcon), + onSelect: () => { + const newTool: StoredTool = { + type: 'workflow', + title: 'Workflow', + toolId: 'workflow_executor', + params: { + workflowId: workflow.id, + }, + isExpanded: true, + usageControl: 'auto', + } + setStoreValue([ + ...selectedTools.map((tool) => ({ ...tool, isExpanded: false })), + newTool, + ]) + setOpen(false) + }, + disabled: isPreview || disabled, + })), + }) + } + return groups }, [ customTools, @@ -1749,6 +1794,7 @@ export function ToolInput({ handleSelectTool, permissionConfig.disableCustomTools, permissionConfig.disableMcpTools, + availableWorkflows, ]) const toolRequiresOAuth = (toolId: string): boolean => { diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/workflow-block.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/workflow-block.tsx index fbd93d2491..8ab6930e6c 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/workflow-block.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/workflow-block.tsx @@ -1021,11 +1021,11 @@ export const WorkflowBlock = memo(function WorkflowBlock({ { e.stopPropagation() - if (childWorkflowId && !isDeploying) { + if (childWorkflowId && !isDeploying && userPermissions.canAdmin) { deployWorkflow(childWorkflowId) } }} @@ -1035,7 +1035,11 @@ export const WorkflowBlock = memo(function WorkflowBlock({ - {!childIsDeployed ? 'Click to deploy' : 'Click to redeploy'} + {!userPermissions.canAdmin + ? 'Admin permission required to deploy' + : !childIsDeployed + ? 'Click to deploy' + : 'Click to redeploy'} diff --git a/apps/sim/tools/params.ts b/apps/sim/tools/params.ts index 28f561ae08..e4a92e67ed 100644 --- a/apps/sim/tools/params.ts +++ b/apps/sim/tools/params.ts @@ -163,7 +163,7 @@ export function getToolParametersConfig( id: 'workflowId', type: 'string', required: true, - visibility: 'user-or-llm', + visibility: 'user-only', description: 'The ID of the workflow to execute', uiComponent: { type: 'workflow-selector',