Created table sub block

This commit is contained in:
Emir Karabeg
2025-01-11 21:05:14 -08:00
parent bc7af8c33f
commit ef5c809c75
5 changed files with 123 additions and 3 deletions

View File

@@ -0,0 +1,115 @@
import { Trash2 } from 'lucide-react'
import { useState } from 'react'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { cn } from '@/lib/utils'
interface TableProps {
columns: string[]
}
interface TableRow {
id: string
cells: string[]
}
export function Table({ columns }: TableProps) {
const [rows, setRows] = useState<TableRow[]>([
{ id: crypto.randomUUID(), cells: Array(columns.length).fill('') },
])
const handleCellChange = (
rowIndex: number,
cellIndex: number,
value: string
) => {
setRows((currentRows) => {
const updatedRows = currentRows.map((row, idx) =>
idx === rowIndex
? {
...row,
cells: row.cells.map((cell, cidx) =>
cidx === cellIndex ? value : cell
),
}
: row
)
// Add new row if typing in the last row
if (rowIndex === currentRows.length - 1 && value !== '') {
updatedRows.push({
id: crypto.randomUUID(),
cells: Array(columns.length).fill(''),
})
}
return updatedRows
})
}
const handleDeleteRow = (rowIndex: number) => {
setRows((currentRows) => {
// Don't delete if it's the last row
if (currentRows.length === 1) return currentRows
return currentRows.filter((_, index) => index !== rowIndex)
})
}
return (
<div className="border rounded-md overflow-hidden">
<table className="w-full">
<thead>
<tr className="border-b">
{columns.map((column, index) => (
<th
key={index}
className={cn(
'px-4 py-2 text-left text-sm font-medium',
index < columns.length - 1 && 'border-r'
)}
>
{column}
</th>
))}
</tr>
</thead>
<tbody>
{rows.map((row, rowIndex) => (
<tr key={row.id} className="border-t group relative">
{row.cells.map((cell, cellIndex) => (
<td
key={`${row.id}-${cellIndex}`}
className={cn(
'p-1',
cellIndex < columns.length - 1 && 'border-r'
)}
>
<Input
value={cell}
placeholder={columns[cellIndex]}
onChange={(e) =>
handleCellChange(rowIndex, cellIndex, e.target.value)
}
className="border-0 focus-visible:ring-0 focus-visible:ring-offset-0 text-muted-foreground placeholder:text-muted-foreground/50"
/>
</td>
))}
{rows.length > 1 && (
<td className="w-0 p-0">
<Button
variant="ghost"
size="icon"
className="opacity-0 group-hover:opacity-100 h-8 w-8 absolute right-2 top-1/2 -translate-y-1/2"
onClick={() => handleDeleteRow(rowIndex)}
>
<Trash2 className="h-4 w-4 text-muted-foreground" />
</Button>
</td>
)}
</tr>
))}
</tbody>
</table>
</div>
)
}

View File

@@ -4,6 +4,7 @@ import { ShortInput } from './components/short-input'
import { LongInput } from './components/long-input'
import { Dropdown } from './components/dropdown'
import { SliderInput } from './components/slider-input'
import { Table } from './components/table'
interface SubBlockProps {
config: SubBlockConfig
@@ -36,6 +37,8 @@ export function SubBlock({ config }: SubBlockProps) {
}
/>
)
case 'table':
return <Table columns={config.columns ?? []} />
default:
return null
}

View File

@@ -29,7 +29,7 @@ export const AgentBlock: BlockConfig = {
title: 'Model',
type: 'dropdown',
layout: 'half',
options: ['GPT-4', 'GPT-3.5', 'Claude', 'Gemini'],
options: ['GPT-4o', 'Gemini 2.0', 'Gemini 1.5 Pro', 'DeepSeek V3', 'Grok 2'],
},
{
title: 'Temperature',

View File

@@ -35,8 +35,9 @@ export const ApiBlock: BlockConfig = {
},
{
title: 'Headers',
type: 'long-input',
type: 'table',
layout: 'full',
columns: ['Key', 'Value'],
},
{
title: 'Body',

View File

@@ -4,7 +4,7 @@ import type { JSX } from 'react'
export type BlockType = 'agent' | 'api' | 'conditional'
export type BlockIcon = (props: SVGProps<SVGSVGElement>) => JSX.Element
export type BlockCategory = 'basic' | 'advanced'
export type SubBlockType = 'short-input' | 'long-input' | 'dropdown' | 'slider'
export type SubBlockType = 'short-input' | 'long-input' | 'dropdown' | 'slider' | 'table'
export type SubBlockLayout = 'full' | 'half'
export interface SubBlockConfig {
@@ -14,6 +14,7 @@ export interface SubBlockConfig {
min?: number
max?: number
layout?: SubBlockLayout
columns?: string[]
}
export interface BlockConfig {