From 8dec40f1240b693d4c938688efb07582f677f7ca Mon Sep 17 00:00:00 2001 From: Vikhyath Mondreti Date: Tue, 11 Nov 2025 21:43:12 -0800 Subject: [PATCH] fix(copilot): show subblocks in diff mode --- .../panel-new/components/editor/editor.tsx | 8 +++- .../hooks/use-editor-block-properties.ts | 44 ++++++++++--------- .../hooks/use-editor-subblock-layout.ts | 38 ++++++++++++---- .../tools/server/workflow/edit-workflow.ts | 13 ++++++ apps/sim/triggers/consts.ts | 3 +- 5 files changed, 74 insertions(+), 32 deletions(-) diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel-new/components/editor/editor.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel-new/components/editor/editor.tsx index 0223af1a0d..d7ca887979 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel-new/components/editor/editor.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel-new/components/editor/editor.tsx @@ -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( @@ -95,7 +98,8 @@ export function Editor() { advancedMode, triggerMode, activeWorkflowId, - blockSubBlockValues + blockSubBlockValues, + currentWorkflow.isDiffMode ) // Get block connections diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel-new/components/editor/hooks/use-editor-block-properties.ts b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel-new/components/editor/hooks/use-editor-block-properties.ts index 3e356eef0a..c3d1eab083 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel-new/components/editor/hooks/use-editor-block-properties.ts +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel-new/components/editor/hooks/use-editor-block-properties.ts @@ -1,4 +1,5 @@ -import { useCallback } from 'react' +import { useCallback, useMemo } from 'react' +import { useWorkflowDiffStore } from '@/stores/workflow-diff' import { useWorkflowStore } from '@/stores/workflows/workflow/store' /** @@ -6,28 +7,31 @@ import { useWorkflowStore } from '@/stores/workflows/workflow/store' * 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 } diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel-new/components/editor/hooks/use-editor-subblock-layout.ts b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel-new/components/editor/hooks/use-editor-subblock-layout.ts index 188659306d..1913c84a76 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel-new/components/editor/hooks/use-editor-subblock-layout.ts +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel-new/components/editor/hooks/use-editor-subblock-layout.ts @@ -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' @@ -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( @@ -22,7 +24,8 @@ export function useEditorSubblockLayout( displayAdvancedMode: boolean, displayTriggerMode: boolean, activeWorkflowId: string | null, - blockSubBlockValues: Record + blockSubBlockValues: Record, + isDiffMode: boolean ) { return useMemo(() => { // Guard against missing config or block selection @@ -33,15 +36,28 @@ export function useEditorSubblockLayout( // Get the appropriate state for conditional evaluation let stateToUse: Record = {} - const blocks = useWorkflowStore.getState().blocks || {} + // Get blocks based on whether we're in diff mode + let blocks: Record + 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 } @@ -50,11 +66,14 @@ export function useEditorSubblockLayout( {} as Record ) - 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) => { @@ -134,5 +153,6 @@ export function useEditorSubblockLayout( displayTriggerMode, blockSubBlockValues, activeWorkflowId, + isDiffMode, ]) } diff --git a/apps/sim/lib/copilot/tools/server/workflow/edit-workflow.ts b/apps/sim/lib/copilot/tools/server/workflow/edit-workflow.ts index d4c964eaca..2e6e5ed0f4 100644 --- a/apps/sim/lib/copilot/tools/server/workflow/edit-workflow.ts +++ b/apps/sim/lib/copilot/tools/server/workflow/edit-workflow.ts @@ -131,6 +131,10 @@ function createBlockFromParams(blockId: string, params: any, parentId?: string): const subBlocks: Record = {} 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 } }) } @@ -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 @@ -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) { diff --git a/apps/sim/triggers/consts.ts b/apps/sim/triggers/consts.ts index 3c47d671f5..ff511b2e92 100644 --- a/apps/sim/triggers/consts.ts +++ b/apps/sim/triggers/consts.ts @@ -31,7 +31,7 @@ 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[] = [ @@ -39,4 +39,5 @@ export const TRIGGER_RUNTIME_SUBBLOCK_IDS: string[] = [ 'triggerPath', 'testUrl', 'testUrlExpiresAt', + 'scheduleId', ]