mirror of
https://github.com/simstudioai/sim.git
synced 2026-01-08 22:48:14 -05:00
Added ability for horizontal ports
This commit is contained in:
@@ -2,11 +2,20 @@ import { EdgeProps, getSmoothStepPath } from 'reactflow'
|
||||
import { X } from 'lucide-react'
|
||||
|
||||
export const CustomEdge = (props: EdgeProps) => {
|
||||
const isHorizontal =
|
||||
props.sourcePosition === 'right' || props.sourcePosition === 'left'
|
||||
|
||||
// For horizontal handles, we'll add a minimum extension to ensure the path
|
||||
// always goes outward before going up/down
|
||||
const [edgePath] = getSmoothStepPath({
|
||||
sourceX: props.sourceX,
|
||||
sourceY: props.sourceY,
|
||||
sourcePosition: props.sourcePosition,
|
||||
targetX: props.targetX,
|
||||
targetY: props.targetY,
|
||||
targetPosition: props.targetPosition,
|
||||
borderRadius: 8,
|
||||
offset: isHorizontal ? 30 : 20, // Increased offset for horizontal handles to ensure outward extension
|
||||
})
|
||||
|
||||
const midPoint = {
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Trash2, Play, Circle, CircleOff, Copy } from 'lucide-react'
|
||||
import {
|
||||
Trash2,
|
||||
Play,
|
||||
Circle,
|
||||
CircleOff,
|
||||
Copy,
|
||||
ArrowLeftRight,
|
||||
ArrowUpDown,
|
||||
} from 'lucide-react'
|
||||
import { useWorkflowStore } from '@/stores/workflow/workflow-store'
|
||||
import {
|
||||
Tooltip,
|
||||
@@ -17,10 +25,16 @@ export function ActionBar({ blockId }: ActionBarProps) {
|
||||
const toggleBlockEnabled = useWorkflowStore(
|
||||
(state) => state.toggleBlockEnabled
|
||||
)
|
||||
const toggleBlockHandles = useWorkflowStore(
|
||||
(state) => state.toggleBlockHandles
|
||||
)
|
||||
const duplicateBlock = useWorkflowStore((state) => state.duplicateBlock)
|
||||
const isEnabled = useWorkflowStore(
|
||||
(state) => state.blocks[blockId]?.enabled ?? true
|
||||
)
|
||||
const horizontalHandles = useWorkflowStore(
|
||||
(state) => state.blocks[blockId]?.horizontalHandles ?? false
|
||||
)
|
||||
|
||||
return (
|
||||
<div className="absolute top-0 -right-20 flex flex-col items-center gap-2 p-2 bg-white rounded-md shadow-sm border border-gray-200 animate-in fade-in slide-in-from-left-2">
|
||||
@@ -75,6 +89,26 @@ export function ActionBar({ blockId }: ActionBarProps) {
|
||||
<TooltipContent side="right">Duplicate Block</TooltipContent>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => toggleBlockHandles(blockId)}
|
||||
className="text-gray-500"
|
||||
>
|
||||
{horizontalHandles ? (
|
||||
<ArrowLeftRight className="h-4 w-4" />
|
||||
) : (
|
||||
<ArrowUpDown className="h-4 w-4" />
|
||||
)}
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="right">
|
||||
{horizontalHandles ? 'Vertical Ports' : 'Horizontal Ports'}
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
|
||||
@@ -17,7 +17,7 @@ export function LongInput({
|
||||
return (
|
||||
<Textarea
|
||||
className="w-full resize-none placeholder:text-muted-foreground/50 allow-scroll"
|
||||
rows={3}
|
||||
rows={4}
|
||||
placeholder={placeholder ?? ''}
|
||||
value={value?.toString() ?? ''}
|
||||
onChange={(e) => setValue(e.target.value)}
|
||||
|
||||
@@ -31,6 +31,9 @@ export function WorkflowBlock({
|
||||
const isEnabled = useWorkflowStore(
|
||||
(state) => state.blocks[id]?.enabled ?? true
|
||||
)
|
||||
const horizontalHandles = useWorkflowStore(
|
||||
(state) => state.blocks[id]?.horizontalHandles ?? false
|
||||
)
|
||||
|
||||
function groupSubBlocks(subBlocks: SubBlockConfig[]) {
|
||||
const rows: SubBlockConfig[][] = []
|
||||
@@ -70,14 +73,14 @@ export function WorkflowBlock({
|
||||
|
||||
<Handle
|
||||
type="target"
|
||||
position={Position.Top}
|
||||
position={horizontalHandles ? Position.Left : Position.Top}
|
||||
className={cn(
|
||||
'!w-3.5 !h-3.5',
|
||||
'!bg-white !rounded-full !border !border-gray-200',
|
||||
'!opacity-0 group-hover:!opacity-100',
|
||||
'!transition-opacity !duration-200 !cursor-crosshair',
|
||||
'hover:!border-blue-500',
|
||||
'!top-[-7px]'
|
||||
horizontalHandles ? '!left-[-7px]' : '!top-[-7px]'
|
||||
)}
|
||||
/>
|
||||
|
||||
@@ -124,14 +127,14 @@ export function WorkflowBlock({
|
||||
|
||||
<Handle
|
||||
type="source"
|
||||
position={Position.Bottom}
|
||||
position={horizontalHandles ? Position.Right : Position.Bottom}
|
||||
className={cn(
|
||||
'!w-3.5 !h-3.5',
|
||||
'!bg-white !rounded-full !border !border-gray-200',
|
||||
'!opacity-0 group-hover:!opacity-100',
|
||||
'!transition-opacity !duration-200 !cursor-crosshair',
|
||||
'hover:!border-blue-500',
|
||||
'!bottom-[-7px]'
|
||||
horizontalHandles ? '!right-[-7px]' : '!bottom-[-7px]'
|
||||
)}
|
||||
/>
|
||||
</Card>
|
||||
|
||||
@@ -15,6 +15,7 @@ export interface BlockState {
|
||||
subBlocks: Record<string, SubBlockState>
|
||||
outputs: Record<string, OutputType>
|
||||
enabled: boolean
|
||||
horizontalHandles?: boolean
|
||||
}
|
||||
|
||||
export interface SubBlockState {
|
||||
@@ -45,6 +46,7 @@ export interface WorkflowActions {
|
||||
updateLastSaved: () => void
|
||||
toggleBlockEnabled: (id: string) => void
|
||||
duplicateBlock: (id: string) => void
|
||||
toggleBlockHandles: (id: string) => void
|
||||
}
|
||||
|
||||
export type WorkflowStore = WorkflowState & WorkflowActions
|
||||
@@ -211,7 +211,6 @@ const initializeRegistry = () => {
|
||||
})
|
||||
}
|
||||
|
||||
// Call this in your app's entry point
|
||||
if (typeof window !== 'undefined') {
|
||||
initializeRegistry()
|
||||
}
|
||||
|
||||
@@ -242,6 +242,22 @@ export const useWorkflowStore = create<WorkflowStoreWithHistory>()(
|
||||
pushHistory(set, get, newState, `Duplicate ${block.type} block`)
|
||||
get().updateLastSaved()
|
||||
},
|
||||
|
||||
toggleBlockHandles: (id: string) => {
|
||||
const newState = {
|
||||
blocks: {
|
||||
...get().blocks,
|
||||
[id]: {
|
||||
...get().blocks[id],
|
||||
horizontalHandles: !get().blocks[id].horizontalHandles,
|
||||
},
|
||||
},
|
||||
edges: [...get().edges],
|
||||
}
|
||||
|
||||
set(newState)
|
||||
get().updateLastSaved()
|
||||
},
|
||||
})),
|
||||
{ name: 'workflow-store' }
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user