Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ import {
Input,
Label,
Textarea,
Tooltip,
} from '@sim/emcn'
import { Trash } from '@sim/emcn/icons'
import { generateId } from '@sim/utils/id'
import { Plus } from 'lucide-react'
import { ArrowLeftRight, Plus } from 'lucide-react'
import { useParams } from 'next/navigation'
import { formatDisplayText } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/formatted-text'
import {
Expand Down Expand Up @@ -62,6 +63,12 @@ const BOOLEAN_OPTIONS: ComboboxOption[] = [
{ label: 'false', value: 'false' },
]

/**
* Values representable by the boolean selector; anything else (e.g. a block
* reference) requires the manual input.
*/
const BOOLEAN_LITERALS = new Set(['', 'true', 'false'])

/**
* Parses a value that might be a JSON string or already an array of VariableAssignment.
* This handles the case where workflows are imported with stringified values.
Expand Down Expand Up @@ -116,6 +123,7 @@ export function VariablesInput({
const overlayRefs = useRef<Record<string, HTMLDivElement>>({})
const [dragHighlight, setDragHighlight] = useState<Record<string, boolean>>({})
const [collapsedAssignments, setCollapsedAssignments] = useState<Record<string, boolean>>({})
const [manualBooleanModes, setManualBooleanModes] = useState<Record<string, boolean>>({})

const currentWorkflowVariables = Object.values(workflowVariables).filter(
(v: Variable) => v.workflowId === workflowId
Expand Down Expand Up @@ -375,6 +383,9 @@ export function VariablesInput({
valuePath: [index, 'variableName'],
label: variableLabel,
})
const isManualBoolean =
assignment.type === 'boolean' &&
(manualBooleanModes[assignment.id] ?? !BOOLEAN_LITERALS.has(assignment.value ?? ''))
const booleanLabelHighlight = getWorkflowSearchLabelHighlight({
activeSearchTarget,
blockId,
Expand Down Expand Up @@ -467,8 +478,44 @@ export function VariablesInput({
</div>

<div className='flex flex-col gap-1.5'>
<Label className='text-small'>Value</Label>
{assignment.type === 'boolean' ? (
<div className='flex items-center justify-between'>
<Label className='text-small'>Value</Label>
{assignment.type === 'boolean' && (
<Tooltip.Root>
<Tooltip.Trigger asChild>
<button
type='button'
className='flex size-[12px] flex-shrink-0 items-center justify-center bg-transparent p-0 disabled:cursor-not-allowed disabled:opacity-50'
onClick={() =>
setManualBooleanModes((prev) => ({
...prev,
[assignment.id]: !isManualBoolean,
}))
}
disabled={isReadOnly}
aria-label={
isManualBoolean ? 'Switch to selector' : 'Switch to manual value'
}
>
<ArrowLeftRight
className={cn(
'!h-[12px] !w-[12px]',
isManualBoolean
? 'text-[var(--text-primary)]'
: 'text-[var(--text-secondary)]'
)}
/>
</button>
</Tooltip.Trigger>
<Tooltip.Content side='top'>
<p>
{isManualBoolean ? 'Switch to selector' : 'Switch to manual value'}
</p>
</Tooltip.Content>
</Tooltip.Root>
)}
</div>
{assignment.type === 'boolean' && !isManualBoolean ? (
<Combobox
options={BOOLEAN_OPTIONS}
value={assignment.value ?? ''}
Expand Down
1 change: 1 addition & 0 deletions apps/sim/hooks/use-collaborative-workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1696,6 +1696,7 @@ export function useCollaborativeWorkflow() {

// Apply locally first (immediate UI feedback)
useSubBlockStore.getState().setValue(blockId, subblockId, value)
useWorkflowStore.getState().syncDynamicHandleSubblockValue(blockId, subblockId, value)

if (isSyntheticToolSubBlockId(subblockId)) return

Expand Down
Loading