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 @@ -75,7 +75,10 @@ export function Editor() {
const focusOnBlock = useFocusOnBlock()

// Get block properties (advanced/trigger modes)
const { advancedMode, triggerMode } = useEditorBlockProperties(currentBlockId)
const { advancedMode, triggerMode } = useEditorBlockProperties(
currentBlockId,
currentWorkflow.isDiffMode
)

// Subscribe to block's subblock values
const blockSubBlockValues = useSubBlockStore(
Expand All @@ -95,7 +98,8 @@ export function Editor() {
advancedMode,
triggerMode,
activeWorkflowId,
blockSubBlockValues
blockSubBlockValues,
currentWorkflow.isDiffMode
)

// Get block connections
Expand Down
Original file line number Diff line number Diff line change
@@ -1,33 +1,37 @@
import { useCallback } from 'react'
import { useCallback, useMemo } from 'react'
import { useWorkflowDiffStore } from '@/stores/workflow-diff'
import { useWorkflowStore } from '@/stores/workflows/workflow/store'

/**
* Custom hook for managing block display properties in the editor panel.
* Provides access to advanced mode and trigger mode states.
*
* @param blockId - The ID of the block being edited
* @param isDiffMode - Whether we're currently viewing a diff
* @returns Block display properties (advanced mode, trigger mode)
*/
export function useEditorBlockProperties(blockId: string | null) {
const blockProperties = useWorkflowStore(
useCallback(
(state) => {
if (!blockId) {
return {
advancedMode: false,
triggerMode: false,
}
}
export function useEditorBlockProperties(blockId: string | null, isDiffMode: boolean) {
// Get blocks from appropriate source
const normalBlocks = useWorkflowStore(useCallback((state) => state.blocks, []))
const diffWorkflow = useWorkflowDiffStore(useCallback((state) => state.diffWorkflow, []))

const block = state.blocks[blockId]
return {
advancedMode: block?.advancedMode ?? false,
triggerMode: block?.triggerMode ?? false,
}
},
[blockId]
)
)
const blockProperties = useMemo(() => {
if (!blockId) {
return {
advancedMode: false,
triggerMode: false,
}
}

// Get block from appropriate source based on mode
const blocks = isDiffMode ? (diffWorkflow as any)?.blocks || {} : normalBlocks
const block = blocks[blockId]

return {
advancedMode: block?.advancedMode ?? false,
triggerMode: block?.triggerMode ?? false,
}
}, [blockId, isDiffMode, normalBlocks, diffWorkflow])

return blockProperties
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useMemo } from 'react'
import { getEnv, isTruthy } from '@/lib/env'
import type { BlockConfig, SubBlockConfig, SubBlockType } from '@/blocks/types'
import { useWorkflowDiffStore } from '@/stores/workflow-diff'
import { mergeSubblockState } from '@/stores/workflows/utils'
import { useWorkflowStore } from '@/stores/workflows/workflow/store'

Expand All @@ -14,6 +15,7 @@ import { useWorkflowStore } from '@/stores/workflows/workflow/store'
* @param displayTriggerMode - Whether trigger mode is enabled for this block
* @param activeWorkflowId - The active workflow ID
* @param blockSubBlockValues - Current subblock values from the store
* @param isDiffMode - Whether we're currently viewing a diff
* @returns Object containing subBlocks array and stateToUse for stable key generation
*/
export function useEditorSubblockLayout(
Expand All @@ -22,7 +24,8 @@ export function useEditorSubblockLayout(
displayAdvancedMode: boolean,
displayTriggerMode: boolean,
activeWorkflowId: string | null,
blockSubBlockValues: Record<string, any>
blockSubBlockValues: Record<string, any>,
isDiffMode: boolean
) {
return useMemo(() => {
// Guard against missing config or block selection
Expand All @@ -33,15 +36,28 @@ export function useEditorSubblockLayout(
// Get the appropriate state for conditional evaluation
let stateToUse: Record<string, any> = {}

const blocks = useWorkflowStore.getState().blocks || {}
// Get blocks based on whether we're in diff mode
let blocks: Record<string, any>
if (isDiffMode) {
// In diff mode, get blocks from diff workflow
const diffStore = useWorkflowDiffStore.getState()
const diffWorkflow = diffStore.diffWorkflow
blocks = (diffWorkflow as any)?.blocks || {}
} else {
// In normal mode, get blocks from workflow store
blocks = useWorkflowStore.getState().blocks || {}
}

const mergedMap = mergeSubblockState(blocks, activeWorkflowId || undefined, blockId)
const mergedState = mergedMap ? mergedMap[blockId] : undefined
const mergedSubBlocks = mergedState?.subBlocks || {}

// In diff mode, prioritize diff workflow values; in normal mode, prioritize live store values
stateToUse = Object.keys(mergedSubBlocks).reduce(
(acc, key) => {
const value =
blockSubBlockValues[key] !== undefined
const value = isDiffMode
? (mergedSubBlocks[key]?.value ?? null)
: blockSubBlockValues[key] !== undefined
? blockSubBlockValues[key]
: (mergedSubBlocks[key]?.value ?? null)
acc[key] = { value }
Expand All @@ -50,11 +66,14 @@ export function useEditorSubblockLayout(
{} as Record<string, { value: unknown }>
)

Object.keys(blockSubBlockValues).forEach((key) => {
if (!(key in stateToUse)) {
stateToUse[key] = { value: blockSubBlockValues[key] }
}
})
// Only add live store values if not in diff mode
if (!isDiffMode) {
Object.keys(blockSubBlockValues).forEach((key) => {
if (!(key in stateToUse)) {
stateToUse[key] = { value: blockSubBlockValues[key] }
}
})
}

// Filter visible blocks and those that meet their conditions
const visibleSubBlocks = (config.subBlocks || []).filter((block) => {
Expand Down Expand Up @@ -134,5 +153,6 @@ export function useEditorSubblockLayout(
displayTriggerMode,
blockSubBlockValues,
activeWorkflowId,
isDiffMode,
])
}
13 changes: 13 additions & 0 deletions apps/sim/lib/copilot/tools/server/workflow/edit-workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ function createBlockFromParams(blockId: string, params: any, parentId?: string):
const subBlocks: Record<string, any> = {}
if (params.inputs) {
Object.entries(params.inputs).forEach(([key, value]) => {
// Skip runtime subblock IDs when computing outputs
if (TRIGGER_RUNTIME_SUBBLOCK_IDS.includes(key)) {
return
}
subBlocks[key] = { id: key, type: 'short-input', value: value }
})
}
Expand All @@ -157,6 +161,10 @@ function createBlockFromParams(blockId: string, params: any, parentId?: string):
// Add inputs as subBlocks
if (params.inputs) {
Object.entries(params.inputs).forEach(([key, value]) => {
if (TRIGGER_RUNTIME_SUBBLOCK_IDS.includes(key)) {
return
}

let sanitizedValue = value

// Special handling for inputFormat - ensure it's an array
Expand Down Expand Up @@ -729,6 +737,11 @@ function applyOperationsToWorkflowState(
// Update inputs if provided
if (params.inputs) {
Object.entries(params.inputs).forEach(([key, value]) => {
// Skip runtime subblock IDs (webhookId, triggerPath, testUrl, testUrlExpiresAt, scheduleId)
if (TRIGGER_RUNTIME_SUBBLOCK_IDS.includes(key)) {
return
}

let sanitizedValue = value

if (key === 'inputFormat' && value !== null && value !== undefined) {
Expand Down
3 changes: 2 additions & 1 deletion apps/sim/triggers/consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,13 @@ export const TRIGGER_PERSISTED_SUBBLOCK_IDS: string[] = [
]

/**
* Trigger-related subblock IDs that represent runtime metadata. They should remain
* Trigger and schedule-related subblock IDs that represent runtime metadata. They should remain
* in the workflow state but must not be modified or cleared by diff operations.
*/
export const TRIGGER_RUNTIME_SUBBLOCK_IDS: string[] = [
'webhookId',
'triggerPath',
'testUrl',
'testUrlExpiresAt',
'scheduleId',
]