Files
sim/app/w/components/workflow-block/workflow-block.tsx
2025-01-14 15:39:52 -08:00

99 lines
2.8 KiB
TypeScript

import { Card } from '@/components/ui/card'
import { BlockConfig, SubBlockConfig } from '../../../../blocks/types/block'
import { SubBlock } from './sub-block/sub-block'
import { Handle, Position } from 'reactflow'
import { cn } from '@/lib/utils'
interface WorkflowBlockProps {
id: string
type: string
position: { x: number; y: number }
config: BlockConfig
name: string
}
export function WorkflowBlock({ id, type, config, name }: WorkflowBlockProps) {
const { toolbar, workflow } = config
function groupSubBlocks(subBlocks: SubBlockConfig[]) {
const rows: SubBlockConfig[][] = []
let currentRow: SubBlockConfig[] = []
let currentRowWidth = 0
subBlocks.forEach((block) => {
const blockWidth = block.layout === 'half' ? 0.5 : 1
if (currentRowWidth + blockWidth > 1) {
rows.push([...currentRow])
currentRow = [block]
currentRowWidth = blockWidth
} else {
currentRow.push(block)
currentRowWidth += blockWidth
}
})
if (currentRow.length > 0) {
rows.push(currentRow)
}
return rows
}
const subBlockRows = groupSubBlocks(workflow.subBlocks)
return (
<Card className="w-[320px] shadow-md select-none group">
<Handle
type="target"
position={Position.Top}
className={cn(
'!w-3 !h-3',
'!bg-white !rounded-full !border !border-gray-200',
'!opacity-0 group-hover:!opacity-100',
'!transition-opacity !duration-200 !cursor-crosshair',
'hover:!border-blue-500'
)}
/>
<div className="flex items-center gap-3 p-3 border-b">
<div
className="flex items-center justify-center w-7 h-7 rounded"
style={{ backgroundColor: toolbar.bgColor }}
>
<toolbar.icon className="w-5 h-5 text-white" />
</div>
<span className="font-medium text-md">{name}</span>
</div>
<div className="px-4 pt-3 pb-4 space-y-4">
{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 config={subBlock} />
</div>
))}
</div>
))}
</div>
<Handle
type="source"
position={Position.Bottom}
className={cn(
'!w-3 !h-3',
'!bg-white !rounded-full !border !border-gray-200',
'!opacity-0 group-hover:!opacity-100',
'!transition-opacity !duration-200 !cursor-crosshair',
'hover:!border-blue-500'
)}
/>
</Card>
)
}