Skip to content

Commit e186ea6

Browse files
authored
improvement(ux): optimistic updates for envvars, custom tools, folder operations, workflow deletions. shared hook for connection tags & tag dropdown, fix for triggers not re-rendering on trigger selected (#1861)
1 parent b3490e9 commit e186ea6

File tree

12 files changed

+1109
-590
lines changed

12 files changed

+1109
-590
lines changed

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel-new/components/editor/components/connection-blocks/connection-blocks.tsx

Lines changed: 162 additions & 219 deletions
Large diffs are not rendered by default.

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel-new/components/editor/components/sub-block/components/tag-dropdown.tsx

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,7 @@ export const TagDropdown: React.FC<TagDropdownProps> = ({
493493
(metric: { name: string }) => `${normalizedBlockName}.${metric.name.toLowerCase()}`
494494
)
495495
} else {
496-
const outputPaths = generateOutputPaths(blockConfig.outputs)
496+
const outputPaths = getBlockOutputPaths(sourceBlock.type, mergedSubBlocks)
497497
blockTags = outputPaths.map((path) => `${normalizedBlockName}.${path}`)
498498
}
499499
} else if (sourceBlock.type === 'variables') {
@@ -515,7 +515,11 @@ export const TagDropdown: React.FC<TagDropdownProps> = ({
515515
if (schemaFields.length > 0) {
516516
blockTags = schemaFields.map((field) => `${normalizedBlockName}.${field.name}`)
517517
} else {
518-
const outputPaths = generateOutputPaths(blockConfig.outputs || {})
518+
const outputPaths = getBlockOutputPaths(
519+
sourceBlock.type,
520+
mergedSubBlocks,
521+
sourceBlock.triggerMode
522+
)
519523
blockTags = outputPaths.map((path) => `${normalizedBlockName}.${path}`)
520524
}
521525
} else if (!blockConfig.outputs || Object.keys(blockConfig.outputs).length === 0) {
@@ -573,21 +577,19 @@ export const TagDropdown: React.FC<TagDropdownProps> = ({
573577
if (dynamicOutputs.length > 0) {
574578
blockTags = dynamicOutputs.map((path) => `${normalizedBlockName}.${path}`)
575579
} else {
576-
const outputPaths = generateOutputPaths(blockConfig.outputs || {})
580+
const outputPaths = getBlockOutputPaths(sourceBlock.type, mergedSubBlocks, true)
577581
blockTags = outputPaths.map((path) => `${normalizedBlockName}.${path}`)
578582
}
579583
} else if (sourceBlock.type === 'approval') {
580-
// For approval block, use dynamic outputs based on inputFormat
581584
const dynamicOutputs = getBlockOutputPaths(sourceBlock.type, mergedSubBlocks)
582585

583-
// If it's a self-reference, only show url (available immediately)
584586
const isSelfReference = activeSourceBlockId === blockId
585587

586588
if (dynamicOutputs.length > 0) {
587589
const allTags = dynamicOutputs.map((path) => `${normalizedBlockName}.${path}`)
588590
blockTags = isSelfReference ? allTags.filter((tag) => tag.endsWith('.url')) : allTags
589591
} else {
590-
const outputPaths = generateOutputPaths(blockConfig.outputs || {})
592+
const outputPaths = getBlockOutputPaths(sourceBlock.type, mergedSubBlocks)
591593
const allTags = outputPaths.map((path) => `${normalizedBlockName}.${path}`)
592594
blockTags = isSelfReference ? allTags.filter((tag) => tag.endsWith('.url')) : allTags
593595
}
@@ -601,7 +603,11 @@ export const TagDropdown: React.FC<TagDropdownProps> = ({
601603
if (toolOutputPaths.length > 0) {
602604
blockTags = toolOutputPaths.map((path) => `${normalizedBlockName}.${path}`)
603605
} else {
604-
const outputPaths = generateOutputPaths(blockConfig.outputs || {})
606+
const outputPaths = getBlockOutputPaths(
607+
sourceBlock.type,
608+
mergedSubBlocks,
609+
sourceBlock.triggerMode
610+
)
605611
blockTags = outputPaths.map((path) => `${normalizedBlockName}.${path}`)
606612
}
607613
}
@@ -845,7 +851,7 @@ export const TagDropdown: React.FC<TagDropdownProps> = ({
845851
(metric: { name: string }) => `${normalizedBlockName}.${metric.name.toLowerCase()}`
846852
)
847853
} else {
848-
const outputPaths = generateOutputPaths(blockConfig.outputs)
854+
const outputPaths = getBlockOutputPaths(accessibleBlock.type, mergedSubBlocks)
849855
blockTags = outputPaths.map((path) => `${normalizedBlockName}.${path}`)
850856
}
851857
} else if (accessibleBlock.type === 'variables') {
@@ -867,7 +873,11 @@ export const TagDropdown: React.FC<TagDropdownProps> = ({
867873
if (schemaFields.length > 0) {
868874
blockTags = schemaFields.map((field) => `${normalizedBlockName}.${field.name}`)
869875
} else {
870-
const outputPaths = generateOutputPaths(blockConfig.outputs || {})
876+
const outputPaths = getBlockOutputPaths(
877+
accessibleBlock.type,
878+
mergedSubBlocks,
879+
accessibleBlock.triggerMode
880+
)
871881
blockTags = outputPaths.map((path) => `${normalizedBlockName}.${path}`)
872882
}
873883
} else if (!blockConfig.outputs || Object.keys(blockConfig.outputs).length === 0) {
@@ -879,21 +889,19 @@ export const TagDropdown: React.FC<TagDropdownProps> = ({
879889
if (dynamicOutputs.length > 0) {
880890
blockTags = dynamicOutputs.map((path) => `${normalizedBlockName}.${path}`)
881891
} else {
882-
const outputPaths = generateOutputPaths(blockConfig.outputs || {})
892+
const outputPaths = getBlockOutputPaths(accessibleBlock.type, mergedSubBlocks, true)
883893
blockTags = outputPaths.map((path) => `${normalizedBlockName}.${path}`)
884894
}
885895
} else if (accessibleBlock.type === 'approval') {
886-
// For approval block, use dynamic outputs based on inputFormat
887896
const dynamicOutputs = getBlockOutputPaths(accessibleBlock.type, mergedSubBlocks)
888897

889-
// If it's a self-reference, only show url (available immediately)
890898
const isSelfReference = accessibleBlockId === blockId
891899

892900
if (dynamicOutputs.length > 0) {
893901
const allTags = dynamicOutputs.map((path) => `${normalizedBlockName}.${path}`)
894902
blockTags = isSelfReference ? allTags.filter((tag) => tag.endsWith('.url')) : allTags
895903
} else {
896-
const outputPaths = generateOutputPaths(blockConfig.outputs || {})
904+
const outputPaths = getBlockOutputPaths(accessibleBlock.type, mergedSubBlocks)
897905
const allTags = outputPaths.map((path) => `${normalizedBlockName}.${path}`)
898906
blockTags = isSelfReference ? allTags.filter((tag) => tag.endsWith('.url')) : allTags
899907
}
@@ -907,7 +915,11 @@ export const TagDropdown: React.FC<TagDropdownProps> = ({
907915
if (toolOutputPaths.length > 0) {
908916
blockTags = toolOutputPaths.map((path) => `${normalizedBlockName}.${path}`)
909917
} else {
910-
const outputPaths = generateOutputPaths(blockConfig.outputs || {})
918+
const outputPaths = getBlockOutputPaths(
919+
accessibleBlock.type,
920+
mergedSubBlocks,
921+
accessibleBlock.triggerMode
922+
)
911923
blockTags = outputPaths.map((path) => `${normalizedBlockName}.${path}`)
912924
}
913925
}

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel-new/components/editor/hooks/use-editor-subblock-layout.ts

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,25 @@ export function useEditorSubblockLayout(
3636
const blocks = useWorkflowStore.getState().blocks || {}
3737
const mergedMap = mergeSubblockState(blocks, activeWorkflowId || undefined, blockId)
3838
const mergedState = mergedMap ? mergedMap[blockId] : undefined
39-
stateToUse = mergedState?.subBlocks || {}
39+
const mergedSubBlocks = mergedState?.subBlocks || {}
40+
41+
stateToUse = Object.keys(mergedSubBlocks).reduce(
42+
(acc, key) => {
43+
const value =
44+
blockSubBlockValues[key] !== undefined
45+
? blockSubBlockValues[key]
46+
: (mergedSubBlocks[key]?.value ?? null)
47+
acc[key] = { value }
48+
return acc
49+
},
50+
{} as Record<string, { value: unknown }>
51+
)
52+
53+
Object.keys(blockSubBlockValues).forEach((key) => {
54+
if (!(key in stateToUse)) {
55+
stateToUse[key] = { value: blockSubBlockValues[key] }
56+
}
57+
})
4058

4159
// Filter visible blocks and those that meet their conditions
4260
const visibleSubBlocks = (config.subBlocks || []).filter((block) => {
@@ -59,12 +77,12 @@ export function useEditorSubblockLayout(
5977
if (block.mode === 'advanced' && !displayAdvancedMode) return false
6078
if (block.mode === 'trigger') {
6179
// Show trigger mode blocks only when in trigger mode
62-
return displayTriggerMode
80+
if (!displayTriggerMode) return false
6381
}
6482
}
6583

6684
// When in trigger mode, hide blocks that don't have mode: 'trigger'
67-
if (displayTriggerMode) {
85+
if (displayTriggerMode && block.mode !== 'trigger') {
6886
return false
6987
}
7088

0 commit comments

Comments
 (0)