fix(copilot): show subblocks in diff mode (#1916)

This commit is contained in:
Vikhyath Mondreti
2025-11-11 21:47:58 -08:00
committed by GitHub
parent cbc98ab4f5
commit 5cea73fe91
5 changed files with 74 additions and 32 deletions

View File

@@ -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

View File

@@ -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
}

View File

@@ -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<string, any>
blockSubBlockValues: Record<string, any>,
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<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 }
@@ -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) => {
@@ -134,5 +153,6 @@ export function useEditorSubblockLayout(
displayTriggerMode,
blockSubBlockValues,
activeWorkflowId,
isDiffMode,
])
}

View File

@@ -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 }
})
}
@@ -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) {

View File

@@ -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',
]