mirror of
https://github.com/simstudioai/sim.git
synced 2026-01-09 23:17:59 -05:00
Fix: subblock rendering based on condition of other subblock
This commit is contained in:
@@ -19,18 +19,10 @@ interface SubBlockProps {
|
||||
}
|
||||
|
||||
export function SubBlock({ blockId, config, isConnecting }: SubBlockProps) {
|
||||
const [fieldValue] = useSubBlockValue(blockId, config.condition?.field || '')
|
||||
|
||||
const handleMouseDown = (e: React.MouseEvent) => {
|
||||
e.stopPropagation()
|
||||
}
|
||||
|
||||
// Check if the sub-block should be rendered based on its condition
|
||||
const shouldRender = () => {
|
||||
if (!config.condition) return true
|
||||
return fieldValue === config.condition.value
|
||||
}
|
||||
|
||||
const renderInput = () => {
|
||||
switch (config.type) {
|
||||
case 'short-input':
|
||||
@@ -108,10 +100,6 @@ export function SubBlock({ blockId, config, isConnecting }: SubBlockProps) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!shouldRender()) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="space-y-1" onMouseDown={handleMouseDown}>
|
||||
{config.type !== 'switch' && <Label>{config.title}</Label>}
|
||||
|
||||
@@ -99,16 +99,30 @@ export function WorkflowBlock({ id, data, selected }: NodeProps<WorkflowBlockPro
|
||||
}, [id, blockHeight, updateBlockHeight, updateNodeInternals])
|
||||
|
||||
// SubBlock layout management
|
||||
function groupSubBlocks(subBlocks: SubBlockConfig[]) {
|
||||
const visibleSubBlocks = subBlocks.filter((block) => !block.hidden)
|
||||
function groupSubBlocks(subBlocks: SubBlockConfig[], blockId: string) {
|
||||
const rows: SubBlockConfig[][] = []
|
||||
let currentRow: SubBlockConfig[] = []
|
||||
let currentRowWidth = 0
|
||||
|
||||
// Filter visible blocks and those that meet their conditions
|
||||
const visibleSubBlocks = subBlocks.filter((block) => {
|
||||
if (block.hidden) return false
|
||||
|
||||
// If there's no condition, the block should be shown
|
||||
if (!block.condition) return true
|
||||
|
||||
// Get the value of the field this block depends on
|
||||
const fieldValue =
|
||||
useWorkflowStore.getState().blocks[blockId]?.subBlocks[block.condition.field]?.value
|
||||
return fieldValue === block.condition.value
|
||||
})
|
||||
|
||||
visibleSubBlocks.forEach((block) => {
|
||||
const blockWidth = block.layout === 'half' ? 0.5 : 1
|
||||
if (currentRowWidth + blockWidth > 1) {
|
||||
rows.push([...currentRow])
|
||||
if (currentRow.length > 0) {
|
||||
rows.push([...currentRow])
|
||||
}
|
||||
currentRow = [block]
|
||||
currentRowWidth = blockWidth
|
||||
} else {
|
||||
@@ -124,7 +138,7 @@ export function WorkflowBlock({ id, data, selected }: NodeProps<WorkflowBlockPro
|
||||
return rows
|
||||
}
|
||||
|
||||
const subBlockRows = groupSubBlocks(workflow.subBlocks)
|
||||
const subBlockRows = groupSubBlocks(workflow.subBlocks, id)
|
||||
|
||||
// Name editing handlers
|
||||
const handleNameClick = () => {
|
||||
@@ -236,18 +250,20 @@ export function WorkflowBlock({ id, data, selected }: NodeProps<WorkflowBlockPro
|
||||
|
||||
{/* Block Content */}
|
||||
<div ref={contentRef} className="px-4 pt-3 pb-4 space-y-4 cursor-pointer">
|
||||
{subBlockRows.map((row, rowIndex) => (
|
||||
<div key={`row-${rowIndex}`} className="flex gap-4">
|
||||
{row.map((subBlock, blockIndex) => (
|
||||
<div
|
||||
key={`${id}-${rowIndex}-${blockIndex}`}
|
||||
className={`space-y-1 ${subBlock.layout === 'half' ? 'flex-1' : 'w-full'}`}
|
||||
>
|
||||
<SubBlock blockId={id} config={subBlock} isConnecting={isConnecting} />
|
||||
{subBlockRows.length > 0
|
||||
? subBlockRows.map((row, rowIndex) => (
|
||||
<div key={`row-${rowIndex}`} className="flex gap-4">
|
||||
{row.map((subBlock, blockIndex) => (
|
||||
<div
|
||||
key={`${id}-${rowIndex}-${blockIndex}`}
|
||||
className={cn('space-y-1', subBlock.layout === 'half' ? 'flex-1' : 'w-full')}
|
||||
>
|
||||
<SubBlock blockId={id} config={subBlock} isConnecting={isConnecting} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
))
|
||||
: null}
|
||||
</div>
|
||||
|
||||
{/* Output Handle */}
|
||||
|
||||
@@ -7,7 +7,7 @@ type XResponse = XWriteResponse | XReadResponse | XSearchResponse | XUserRespons
|
||||
export const XBlock: BlockConfig<XResponse> = {
|
||||
type: 'x_block',
|
||||
toolbar: {
|
||||
title: 'X (Twitter)',
|
||||
title: 'X',
|
||||
description: 'Interact with X',
|
||||
bgColor: '#000000', // X's black color
|
||||
icon: xIcon,
|
||||
@@ -105,7 +105,7 @@ export const XBlock: BlockConfig<XResponse> = {
|
||||
id: 'replyTo',
|
||||
title: 'Reply To (Tweet ID)',
|
||||
type: 'short-input',
|
||||
layout: 'half',
|
||||
layout: 'full',
|
||||
placeholder: 'Enter tweet ID to reply to',
|
||||
condition: { field: 'operation', value: 'x_write' },
|
||||
},
|
||||
@@ -113,7 +113,7 @@ export const XBlock: BlockConfig<XResponse> = {
|
||||
id: 'mediaIds',
|
||||
title: 'Media IDs',
|
||||
type: 'short-input',
|
||||
layout: 'half',
|
||||
layout: 'full',
|
||||
placeholder: 'Enter comma-separated media IDs',
|
||||
condition: { field: 'operation', value: 'x_write' },
|
||||
},
|
||||
@@ -122,7 +122,7 @@ export const XBlock: BlockConfig<XResponse> = {
|
||||
id: 'tweetId',
|
||||
title: 'Tweet ID',
|
||||
type: 'short-input',
|
||||
layout: 'half',
|
||||
layout: 'full',
|
||||
placeholder: 'Enter tweet ID to read',
|
||||
condition: { field: 'operation', value: 'x_read' },
|
||||
},
|
||||
@@ -130,7 +130,7 @@ export const XBlock: BlockConfig<XResponse> = {
|
||||
id: 'includeReplies',
|
||||
title: 'Include Replies',
|
||||
type: 'dropdown',
|
||||
layout: 'half',
|
||||
layout: 'full',
|
||||
options: ['true', 'false'],
|
||||
value: () => 'false',
|
||||
condition: { field: 'operation', value: 'x_read' },
|
||||
@@ -148,7 +148,7 @@ export const XBlock: BlockConfig<XResponse> = {
|
||||
id: 'maxResults',
|
||||
title: 'Max Results',
|
||||
type: 'short-input',
|
||||
layout: 'half',
|
||||
layout: 'full',
|
||||
placeholder: '10',
|
||||
condition: { field: 'operation', value: 'x_search' },
|
||||
},
|
||||
@@ -156,7 +156,7 @@ export const XBlock: BlockConfig<XResponse> = {
|
||||
id: 'sortOrder',
|
||||
title: 'Sort Order',
|
||||
type: 'dropdown',
|
||||
layout: 'half',
|
||||
layout: 'full',
|
||||
options: ['recency', 'relevancy'],
|
||||
value: () => 'recency',
|
||||
condition: { field: 'operation', value: 'x_search' },
|
||||
@@ -165,7 +165,7 @@ export const XBlock: BlockConfig<XResponse> = {
|
||||
id: 'startTime',
|
||||
title: 'Start Time',
|
||||
type: 'short-input',
|
||||
layout: 'half',
|
||||
layout: 'full',
|
||||
placeholder: 'YYYY-MM-DDTHH:mm:ssZ',
|
||||
condition: { field: 'operation', value: 'x_search' },
|
||||
},
|
||||
@@ -173,7 +173,7 @@ export const XBlock: BlockConfig<XResponse> = {
|
||||
id: 'endTime',
|
||||
title: 'End Time',
|
||||
type: 'short-input',
|
||||
layout: 'half',
|
||||
layout: 'full',
|
||||
placeholder: 'YYYY-MM-DDTHH:mm:ssZ',
|
||||
condition: { field: 'operation', value: 'x_search' },
|
||||
},
|
||||
@@ -182,7 +182,7 @@ export const XBlock: BlockConfig<XResponse> = {
|
||||
id: 'username',
|
||||
title: 'Username',
|
||||
type: 'short-input',
|
||||
layout: 'half',
|
||||
layout: 'full',
|
||||
placeholder: 'Enter username (without @)',
|
||||
condition: { field: 'operation', value: 'x_user' },
|
||||
},
|
||||
@@ -190,7 +190,7 @@ export const XBlock: BlockConfig<XResponse> = {
|
||||
id: 'includeRecentTweets',
|
||||
title: 'Include Recent Tweets',
|
||||
type: 'dropdown',
|
||||
layout: 'half',
|
||||
layout: 'full',
|
||||
options: ['true', 'false'],
|
||||
value: () => 'false',
|
||||
condition: { field: 'operation', value: 'x_user' },
|
||||
|
||||
Reference in New Issue
Block a user