mirror of
https://github.com/simstudioai/sim.git
synced 2026-01-08 22:48:14 -05:00
fix(block-name): updating block name should update downstream var refs (#2592)
* fix(block-name): updating block name should update downstream var refs * remove random comments
This commit is contained in:
committed by
GitHub
parent
27ec4120bc
commit
66b8434861
@@ -134,7 +134,11 @@ export function Editor() {
|
||||
|
||||
const trimmedName = editedName.trim()
|
||||
if (trimmedName && trimmedName !== currentBlock?.name) {
|
||||
collaborativeUpdateBlockName(currentBlockId, trimmedName)
|
||||
const result = collaborativeUpdateBlockName(currentBlockId, trimmedName)
|
||||
if (!result.success) {
|
||||
// Keep rename mode open on error so user can correct the name
|
||||
return
|
||||
}
|
||||
}
|
||||
setIsRenaming(false)
|
||||
}, [currentBlockId, isRenaming, editedName, currentBlock?.name, collaborativeUpdateBlockName])
|
||||
|
||||
@@ -8,6 +8,7 @@ import { TriggerUtils } from '@/lib/workflows/triggers/triggers'
|
||||
import { useSocket } from '@/app/workspace/providers/socket-provider'
|
||||
import { getBlock } from '@/blocks'
|
||||
import { useUndoRedo } from '@/hooks/use-undo-redo'
|
||||
import { useNotificationStore } from '@/stores/notifications'
|
||||
import { registerEmitFunctions, useOperationQueue } from '@/stores/operation-queue/store'
|
||||
import { usePanelEditorStore } from '@/stores/panel/editor/store'
|
||||
import { useVariablesStore } from '@/stores/panel/variables/store'
|
||||
@@ -15,7 +16,7 @@ import { useUndoRedoStore } from '@/stores/undo-redo'
|
||||
import { useWorkflowDiffStore } from '@/stores/workflow-diff/store'
|
||||
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
|
||||
import { useSubBlockStore } from '@/stores/workflows/subblock/store'
|
||||
import { getUniqueBlockName, mergeSubblockState } from '@/stores/workflows/utils'
|
||||
import { getUniqueBlockName, mergeSubblockState, normalizeName } from '@/stores/workflows/utils'
|
||||
import { useWorkflowStore } from '@/stores/workflows/workflow/store'
|
||||
import type { BlockState, Position } from '@/stores/workflows/workflow/types'
|
||||
|
||||
@@ -1016,14 +1017,43 @@ export function useCollaborativeWorkflow() {
|
||||
)
|
||||
|
||||
const collaborativeUpdateBlockName = useCallback(
|
||||
(id: string, name: string) => {
|
||||
executeQueuedOperation('update-name', 'block', { id, name }, () => {
|
||||
const result = workflowStore.updateBlockName(id, name)
|
||||
(id: string, name: string): { success: boolean; error?: string } => {
|
||||
const trimmedName = name.trim()
|
||||
const normalizedNewName = normalizeName(trimmedName)
|
||||
|
||||
if (!normalizedNewName) {
|
||||
logger.error('Cannot rename block to empty name')
|
||||
useNotificationStore.getState().addNotification({
|
||||
level: 'error',
|
||||
message: 'Block name cannot be empty',
|
||||
workflowId: activeWorkflowId || undefined,
|
||||
})
|
||||
return { success: false, error: 'Block name cannot be empty' }
|
||||
}
|
||||
|
||||
const currentBlocks = workflowStore.blocks
|
||||
const conflictingBlock = Object.entries(currentBlocks).find(
|
||||
([blockId, block]) => blockId !== id && normalizeName(block.name) === normalizedNewName
|
||||
)
|
||||
|
||||
if (conflictingBlock) {
|
||||
const conflictName = conflictingBlock[1].name
|
||||
logger.error(`Cannot rename block to "${trimmedName}" - conflicts with "${conflictName}"`)
|
||||
useNotificationStore.getState().addNotification({
|
||||
level: 'error',
|
||||
message: `Block name "${trimmedName}" already exists`,
|
||||
workflowId: activeWorkflowId || undefined,
|
||||
})
|
||||
return { success: false, error: `Block name "${trimmedName}" already exists` }
|
||||
}
|
||||
|
||||
executeQueuedOperation('update-name', 'block', { id, name: trimmedName }, () => {
|
||||
const result = workflowStore.updateBlockName(id, trimmedName)
|
||||
|
||||
if (result.success && result.changedSubblocks.length > 0) {
|
||||
logger.info('Emitting cascaded subblock updates from block rename', {
|
||||
blockId: id,
|
||||
newName: name,
|
||||
newName: trimmedName,
|
||||
updateCount: result.changedSubblocks.length,
|
||||
})
|
||||
|
||||
@@ -1043,7 +1073,7 @@ export function useCollaborativeWorkflow() {
|
||||
operation: {
|
||||
operation: 'subblock-update',
|
||||
target: 'subblock',
|
||||
payload: { blockId, subBlockId, value: newValue },
|
||||
payload: { blockId, subblockId: subBlockId, value: newValue },
|
||||
},
|
||||
workflowId: activeWorkflowId || '',
|
||||
userId: session?.user?.id || 'unknown',
|
||||
@@ -1052,6 +1082,8 @@ export function useCollaborativeWorkflow() {
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
return { success: true }
|
||||
},
|
||||
[executeQueuedOperation, workflowStore, addToQueue, activeWorkflowId, session?.user?.id]
|
||||
)
|
||||
|
||||
@@ -716,54 +716,62 @@ export const useWorkflowStore = create<WorkflowStore>()(
|
||||
const workflowValues = subBlockStore.workflowValues[activeWorkflowId] || {}
|
||||
const updatedWorkflowValues = { ...workflowValues }
|
||||
|
||||
// Helper function to recursively update references in any data structure
|
||||
function updateReferences(value: any, regex: RegExp, replacement: string): any {
|
||||
// Handle string values
|
||||
if (typeof value === 'string') {
|
||||
return regex.test(value) ? value.replace(regex, replacement) : value
|
||||
}
|
||||
|
||||
// Handle arrays
|
||||
if (Array.isArray(value)) {
|
||||
return value.map((item) => updateReferences(item, regex, replacement))
|
||||
}
|
||||
|
||||
// Handle objects
|
||||
if (value !== null && typeof value === 'object') {
|
||||
const result = { ...value }
|
||||
for (const key in result) {
|
||||
result[key] = updateReferences(result[key], regex, replacement)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Return unchanged for other types
|
||||
return value
|
||||
}
|
||||
|
||||
const oldBlockName = normalizeName(oldBlock.name)
|
||||
const newBlockName = normalizeName(name)
|
||||
const regex = new RegExp(`<${oldBlockName}\\.`, 'g')
|
||||
|
||||
// Loop through blocks
|
||||
Object.entries(workflowValues).forEach(([blockId, blockValues]) => {
|
||||
if (blockId === id) return // Skip the block being renamed
|
||||
|
||||
let blockHasChanges = false
|
||||
const updatedBlockValues = { ...blockValues }
|
||||
|
||||
// Loop through subblocks and update references
|
||||
Object.entries(blockValues).forEach(([subBlockId, value]) => {
|
||||
const oldBlockName = normalizeName(oldBlock.name)
|
||||
const newBlockName = normalizeName(name)
|
||||
const regex = new RegExp(`<${oldBlockName}\\.`, 'g')
|
||||
|
||||
// Use a recursive function to handle all object types
|
||||
const updatedValue = updateReferences(value, regex, `<${newBlockName}.`)
|
||||
|
||||
// Check if the value actually changed
|
||||
if (JSON.stringify(updatedValue) !== JSON.stringify(value)) {
|
||||
updatedWorkflowValues[blockId][subBlockId] = updatedValue
|
||||
updatedBlockValues[subBlockId] = updatedValue
|
||||
blockHasChanges = true
|
||||
changedSubblocks.push({
|
||||
blockId,
|
||||
subBlockId,
|
||||
newValue: updatedValue,
|
||||
})
|
||||
}
|
||||
|
||||
// Helper function to recursively update references in any data structure
|
||||
function updateReferences(value: any, regex: RegExp, replacement: string): any {
|
||||
// Handle string values
|
||||
if (typeof value === 'string') {
|
||||
return regex.test(value) ? value.replace(regex, replacement) : value
|
||||
}
|
||||
|
||||
// Handle arrays
|
||||
if (Array.isArray(value)) {
|
||||
return value.map((item) => updateReferences(item, regex, replacement))
|
||||
}
|
||||
|
||||
// Handle objects
|
||||
if (value !== null && typeof value === 'object') {
|
||||
const result = { ...value }
|
||||
for (const key in result) {
|
||||
result[key] = updateReferences(result[key], regex, replacement)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Return unchanged for other types
|
||||
return value
|
||||
}
|
||||
})
|
||||
|
||||
if (blockHasChanges) {
|
||||
updatedWorkflowValues[blockId] = updatedBlockValues
|
||||
}
|
||||
})
|
||||
|
||||
// Update the subblock store with the new values
|
||||
|
||||
Reference in New Issue
Block a user