Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,4 @@ export { Text } from './text/text'
export { TimeInput } from './time-input/time-input'
export { ToolInput } from './tool-input/tool-input'
export { VariablesInput } from './variables-input/variables-input'
export { WorkflowSelectorInput } from './workflow-selector/workflow-selector-input'
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
'use client'

import { useMemo } from 'react'
import { SelectorCombobox } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/selector-combobox/selector-combobox'
import type { SubBlockConfig } from '@/blocks/types'
import type { SelectorContext } from '@/hooks/selectors/types'
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'

interface WorkflowSelectorInputProps {
blockId: string
subBlock: SubBlockConfig
disabled?: boolean
isPreview?: boolean
previewValue?: string | null
}

export function WorkflowSelectorInput({
blockId,
subBlock,
disabled = false,
isPreview = false,
previewValue,
}: WorkflowSelectorInputProps) {
const activeWorkflowId = useWorkflowRegistry((s) => s.activeWorkflowId)

const context: SelectorContext = useMemo(
() => ({
excludeWorkflowId: activeWorkflowId ?? undefined,
}),
[activeWorkflowId]
)

return (
<SelectorCombobox
blockId={blockId}
subBlock={subBlock}
selectorKey='sim.workflows'
selectorContext={context}
disabled={disabled}
isPreview={isPreview}
previewValue={previewValue}
placeholder={subBlock.placeholder || 'Select workflow...'}
/>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {
TimeInput,
ToolInput,
VariablesInput,
WorkflowSelectorInput,
} from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components'
import { useDependsOnGate } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-depends-on-gate'
import type { SubBlockConfig } from '@/blocks/types'
Expand Down Expand Up @@ -90,7 +91,6 @@ const isFieldRequired = (config: SubBlockConfig, subBlockValues?: Record<string,
if (!config.required) return false
if (typeof config.required === 'boolean') return config.required

// Helper function to evaluate a condition
const evalCond = (
cond: {
field: string
Expand Down Expand Up @@ -132,7 +132,6 @@ const isFieldRequired = (config: SubBlockConfig, subBlockValues?: Record<string,
return match
}

// If required is a condition object or function, evaluate it
const condition = typeof config.required === 'function' ? config.required() : config.required
return evalCond(condition, subBlockValues || {})
}
Expand Down Expand Up @@ -378,7 +377,6 @@ function SubBlockComponent({
setIsValidJson(isValid)
}

// Check if wand is enabled for this sub-block
const isWandEnabled = config.wandConfig?.enabled ?? false

/**
Expand Down Expand Up @@ -438,8 +436,6 @@ function SubBlockComponent({
| null
| undefined

// Use dependsOn gating to compute final disabled state
// Only pass previewContextValues when in preview mode to avoid format mismatches
const { finalDisabled: gatedDisabled } = useDependsOnGate(blockId, config, {
disabled,
isPreview,
Expand Down Expand Up @@ -869,6 +865,17 @@ function SubBlockComponent({
/>
)

case 'workflow-selector':
return (
<WorkflowSelectorInput
blockId={blockId}
subBlock={config}
disabled={isDisabled}
isPreview={isPreview}
previewValue={previewValue as string | null}
/>
)

case 'mcp-server-selector':
return (
<McpServerSelector
Expand Down
28 changes: 1 addition & 27 deletions apps/sim/blocks/blocks/workflow.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,5 @@
import { createLogger } from '@sim/logger'
import { WorkflowIcon } from '@/components/icons'
import type { BlockConfig } from '@/blocks/types'
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'

const logger = createLogger('WorkflowBlock')

// Helper function to get available workflows for the dropdown
const getAvailableWorkflows = (): Array<{ label: string; id: string }> => {
try {
const { workflows, activeWorkflowId } = useWorkflowRegistry.getState()

// Filter out the current workflow to prevent recursion
const availableWorkflows = Object.entries(workflows)
.filter(([id]) => id !== activeWorkflowId)
.map(([id, workflow]) => ({
label: workflow.name || `Workflow ${id.slice(0, 8)}`,
id: id,
}))
.sort((a, b) => a.label.localeCompare(b.label))

return availableWorkflows
} catch (error) {
logger.error('Error getting available workflows:', error)
return []
}
}

export const WorkflowBlock: BlockConfig = {
type: 'workflow',
Expand All @@ -38,8 +13,7 @@ export const WorkflowBlock: BlockConfig = {
{
id: 'workflowId',
title: 'Select Workflow',
type: 'combobox',
options: getAvailableWorkflows,
type: 'workflow-selector',
placeholder: 'Search workflows...',
required: true,
},
Expand Down
19 changes: 2 additions & 17 deletions apps/sim/blocks/blocks/workflow_input.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,5 @@
import { WorkflowIcon } from '@/components/icons'
import type { BlockConfig } from '@/blocks/types'
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'

const getAvailableWorkflows = (): Array<{ label: string; id: string }> => {
try {
const { workflows, activeWorkflowId } = useWorkflowRegistry.getState()
return Object.entries(workflows)
.filter(([id]) => id !== activeWorkflowId)
.map(([id, w]) => ({ label: w.name || `Workflow ${id.slice(0, 8)}`, id }))
.sort((a, b) => a.label.localeCompare(b.label))
} catch {
return []
}
}

export const WorkflowInputBlock: BlockConfig = {
type: 'workflow_input',
Expand All @@ -25,18 +12,16 @@ export const WorkflowInputBlock: BlockConfig = {
`,
category: 'blocks',
docsLink: 'https://docs.sim.ai/blocks/workflow',
bgColor: '#6366F1', // Indigo - modern and professional
bgColor: '#6366F1',
icon: WorkflowIcon,
subBlocks: [
{
id: 'workflowId',
title: 'Select Workflow',
type: 'combobox',
options: getAvailableWorkflows,
type: 'workflow-selector',
placeholder: 'Search workflows...',
required: true,
},
// Renders dynamic mapping UI based on selected child workflow's Start trigger inputFormat
{
id: 'inputMapping',
title: 'Input Mapping',
Expand Down
31 changes: 31 additions & 0 deletions apps/sim/hooks/selectors/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type {
SelectorOption,
SelectorQueryArgs,
} from '@/hooks/selectors/types'
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'

const SELECTOR_STALE = 60 * 1000

Expand Down Expand Up @@ -853,6 +854,36 @@ const registry: Record<SelectorKey, SelectorDefinition> = {
}))
},
},
'sim.workflows': {
key: 'sim.workflows',
staleTime: 0, // Always fetch fresh from store
getQueryKey: ({ context }: SelectorQueryArgs) => [
'selectors',
'sim.workflows',
context.excludeWorkflowId ?? 'none',
],
enabled: () => true,
fetchList: async ({ context }: SelectorQueryArgs): Promise<SelectorOption[]> => {
const { workflows } = useWorkflowRegistry.getState()
return Object.entries(workflows)
.filter(([id]) => id !== context.excludeWorkflowId)
.map(([id, workflow]) => ({
id,
label: workflow.name || `Workflow ${id.slice(0, 8)}`,
}))
.sort((a, b) => a.label.localeCompare(b.label))
},
fetchById: async ({ detailId }: SelectorQueryArgs): Promise<SelectorOption | null> => {
if (!detailId) return null
const { workflows } = useWorkflowRegistry.getState()
const workflow = workflows[detailId]
if (!workflow) return null
return {
id: detailId,
label: workflow.name || `Workflow ${detailId.slice(0, 8)}`,
}
},
},
}

export function getSelectorDefinition(key: SelectorKey): SelectorDefinition {
Expand Down
2 changes: 2 additions & 0 deletions apps/sim/hooks/selectors/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export type SelectorKey =
| 'webflow.sites'
| 'webflow.collections'
| 'webflow.items'
| 'sim.workflows'

export interface SelectorOption {
id: string
Expand All @@ -52,6 +53,7 @@ export interface SelectorContext {
siteId?: string
collectionId?: string
spreadsheetId?: string
excludeWorkflowId?: string
}

export interface SelectorQueryArgs {
Expand Down