Skip to content

Commit cd48cd4

Browse files
authored
fix(start): fix start drag from toolbar (#1882)
* Fix start block * Fix webhook * Remove comments
1 parent 4b37f92 commit cd48cd4

File tree

4 files changed

+143
-6
lines changed

4 files changed

+143
-6
lines changed

apps/sim/hooks/use-collaborative-workflow.ts

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -762,13 +762,39 @@ export function useCollaborativeWorkflow() {
762762
// Generate subBlocks and outputs from the block configuration
763763
const subBlocks: Record<string, any> = {}
764764

765-
// Create subBlocks from the block configuration
766765
if (blockConfig.subBlocks) {
767766
blockConfig.subBlocks.forEach((subBlock) => {
767+
let initialValue: unknown = null
768+
769+
if (typeof subBlock.value === 'function') {
770+
try {
771+
initialValue = subBlock.value({})
772+
} catch (error) {
773+
logger.warn('Failed to resolve dynamic sub-block default value', {
774+
subBlockId: subBlock.id,
775+
error: error instanceof Error ? error.message : String(error),
776+
})
777+
}
778+
} else if (subBlock.defaultValue !== undefined) {
779+
initialValue = subBlock.defaultValue
780+
} else if (subBlock.type === 'input-format') {
781+
initialValue = [
782+
{
783+
id: crypto.randomUUID(),
784+
name: '',
785+
type: 'string',
786+
value: '',
787+
collapsed: false,
788+
},
789+
]
790+
} else if (subBlock.type === 'table') {
791+
initialValue = []
792+
}
793+
768794
subBlocks[subBlock.id] = {
769795
id: subBlock.id,
770796
type: subBlock.type,
771-
value: subBlock.defaultValue ?? null,
797+
value: initialValue,
772798
}
773799
})
774800
}

apps/sim/lib/workflows/defaults.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,19 @@ function resolveInitialValue(subBlock: SubBlockConfig): unknown {
3737
return cloneDefaultValue(subBlock.defaultValue)
3838
}
3939

40-
// Ensure structured fields are initialized with empty collections by default
41-
if (subBlock.type === 'input-format' || subBlock.type === 'table') {
40+
if (subBlock.type === 'input-format') {
41+
return [
42+
{
43+
id: crypto.randomUUID(),
44+
name: '',
45+
type: 'string',
46+
value: '',
47+
collapsed: false,
48+
},
49+
]
50+
}
51+
52+
if (subBlock.type === 'table') {
4253
return []
4354
}
4455

apps/sim/lib/workflows/trigger-utils.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ export function getAllTriggerBlocks(): TriggerInfo[] {
124124
icon: block.icon,
125125
color: block.bgColor,
126126
category: 'core',
127+
enableTriggerMode: hasTriggerCapability(block),
127128
})
128129
}
129130
// Check if it's a tool with trigger capability (has trigger-config subblock)
@@ -153,9 +154,15 @@ export function getAllTriggerBlocks(): TriggerInfo[] {
153154
* Check if a block has trigger capability (contains trigger mode subblocks)
154155
*/
155156
export function hasTriggerCapability(block: BlockConfig): boolean {
157+
const hasTriggerModeSubBlocks = block.subBlocks.some((subBlock) => subBlock.mode === 'trigger')
158+
159+
if (block.category === 'triggers') {
160+
return hasTriggerModeSubBlocks
161+
}
162+
156163
return (
157164
(block.triggers?.enabled === true && block.triggers.available.length > 0) ||
158-
block.subBlocks.some((subBlock) => subBlock.mode === 'trigger')
165+
hasTriggerModeSubBlocks
159166
)
160167
}
161168

apps/sim/stores/workflows/workflow/store.ts

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { devtools } from 'zustand/middleware'
44
import { createLogger } from '@/lib/logs/console/logger'
55
import { getBlockOutputs } from '@/lib/workflows/block-outputs'
66
import { getBlock } from '@/blocks'
7+
import type { SubBlockConfig } from '@/blocks/types'
78
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
89
import { useSubBlockStore } from '@/stores/workflows/subblock/store'
910
import {
@@ -21,6 +22,72 @@ import { generateLoopBlocks, generateParallelBlocks } from '@/stores/workflows/w
2122

2223
const logger = createLogger('WorkflowStore')
2324

25+
/**
26+
* Creates a deep clone of an initial sub-block value to avoid shared references.
27+
*
28+
* @param value - The value to clone.
29+
* @returns A cloned value suitable for initializing sub-block state.
30+
*/
31+
function cloneInitialSubblockValue(value: unknown): unknown {
32+
if (Array.isArray(value)) {
33+
return value.map((item) => cloneInitialSubblockValue(item))
34+
}
35+
36+
if (value && typeof value === 'object') {
37+
return Object.entries(value as Record<string, unknown>).reduce<Record<string, unknown>>(
38+
(acc, [key, entry]) => {
39+
acc[key] = cloneInitialSubblockValue(entry)
40+
return acc
41+
},
42+
{}
43+
)
44+
}
45+
46+
return value ?? null
47+
}
48+
49+
/**
50+
* Resolves the initial value for a sub-block based on its configuration.
51+
*
52+
* @param config - The sub-block configuration.
53+
* @returns The resolved initial value or null when no defaults are defined.
54+
*/
55+
function resolveInitialSubblockValue(config: SubBlockConfig): unknown {
56+
if (typeof config.value === 'function') {
57+
try {
58+
const resolved = config.value({})
59+
return cloneInitialSubblockValue(resolved)
60+
} catch (error) {
61+
logger.warn('Failed to resolve dynamic sub-block default value', {
62+
subBlockId: config.id,
63+
error: error instanceof Error ? error.message : String(error),
64+
})
65+
}
66+
}
67+
68+
if (config.defaultValue !== undefined) {
69+
return cloneInitialSubblockValue(config.defaultValue)
70+
}
71+
72+
if (config.type === 'input-format') {
73+
return [
74+
{
75+
id: crypto.randomUUID(),
76+
name: '',
77+
type: 'string',
78+
value: '',
79+
collapsed: false,
80+
},
81+
]
82+
}
83+
84+
if (config.type === 'table') {
85+
return []
86+
}
87+
88+
return null
89+
}
90+
2491
const initialState = {
2592
blocks: {},
2693
edges: [],
@@ -106,12 +173,38 @@ export const useWorkflowStore = create<WorkflowStore>()(
106173
}
107174

108175
const subBlocks: Record<string, SubBlockState> = {}
176+
const subBlockStore = useSubBlockStore.getState()
177+
const activeWorkflowId = useWorkflowRegistry.getState().activeWorkflowId
178+
109179
blockConfig.subBlocks.forEach((subBlock) => {
110180
const subBlockId = subBlock.id
181+
const initialValue = resolveInitialSubblockValue(subBlock)
182+
const normalizedValue =
183+
initialValue !== undefined && initialValue !== null ? initialValue : null
184+
111185
subBlocks[subBlockId] = {
112186
id: subBlockId,
113187
type: subBlock.type,
114-
value: null,
188+
value: normalizedValue as SubBlockState['value'],
189+
}
190+
191+
if (activeWorkflowId) {
192+
try {
193+
const valueToStore =
194+
initialValue !== undefined ? cloneInitialSubblockValue(initialValue) : null
195+
subBlockStore.setValue(id, subBlockId, valueToStore)
196+
} catch (error) {
197+
logger.warn('Failed to seed sub-block store value during block creation', {
198+
blockId: id,
199+
subBlockId,
200+
error: error instanceof Error ? error.message : String(error),
201+
})
202+
}
203+
} else {
204+
logger.warn('Cannot seed sub-block store value: activeWorkflowId not available', {
205+
blockId: id,
206+
subBlockId,
207+
})
115208
}
116209
})
117210

0 commit comments

Comments
 (0)