From ef5c809c7530a7eecf9a2c88d33999a23daa5b55 Mon Sep 17 00:00:00 2001 From: Emir Karabeg Date: Sat, 11 Jan 2025 21:05:14 -0800 Subject: [PATCH] Created table sub block --- .../sub-block/components/table.tsx | 115 ++++++++++++++++++ .../workflow-block/sub-block/sub-block.tsx | 3 + app/w/components/blocks/configs/agent.ts | 2 +- app/w/components/blocks/configs/api.ts | 3 +- app/w/components/blocks/types/block.ts | 3 +- 5 files changed, 123 insertions(+), 3 deletions(-) create mode 100644 app/w/components/blocks/components/workflow-block/sub-block/components/table.tsx diff --git a/app/w/components/blocks/components/workflow-block/sub-block/components/table.tsx b/app/w/components/blocks/components/workflow-block/sub-block/components/table.tsx new file mode 100644 index 000000000..d42cca7bb --- /dev/null +++ b/app/w/components/blocks/components/workflow-block/sub-block/components/table.tsx @@ -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([ + { 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 ( +
+ + + + {columns.map((column, index) => ( + + ))} + + + + {rows.map((row, rowIndex) => ( + + {row.cells.map((cell, cellIndex) => ( + + ))} + {rows.length > 1 && ( + + )} + + ))} + +
+ {column} +
+ + 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" + /> + + +
+
+ ) +} diff --git a/app/w/components/blocks/components/workflow-block/sub-block/sub-block.tsx b/app/w/components/blocks/components/workflow-block/sub-block/sub-block.tsx index b91f8e9ea..f6f72b24d 100644 --- a/app/w/components/blocks/components/workflow-block/sub-block/sub-block.tsx +++ b/app/w/components/blocks/components/workflow-block/sub-block/sub-block.tsx @@ -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 default: return null } diff --git a/app/w/components/blocks/configs/agent.ts b/app/w/components/blocks/configs/agent.ts index 5193db5a1..6d4348056 100644 --- a/app/w/components/blocks/configs/agent.ts +++ b/app/w/components/blocks/configs/agent.ts @@ -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', diff --git a/app/w/components/blocks/configs/api.ts b/app/w/components/blocks/configs/api.ts index 134fec93a..09f7dcdc0 100644 --- a/app/w/components/blocks/configs/api.ts +++ b/app/w/components/blocks/configs/api.ts @@ -35,8 +35,9 @@ export const ApiBlock: BlockConfig = { }, { title: 'Headers', - type: 'long-input', + type: 'table', layout: 'full', + columns: ['Key', 'Value'], }, { title: 'Body', diff --git a/app/w/components/blocks/types/block.ts b/app/w/components/blocks/types/block.ts index ca4bff8e2..6a095f527 100644 --- a/app/w/components/blocks/types/block.ts +++ b/app/w/components/blocks/types/block.ts @@ -4,7 +4,7 @@ import type { JSX } from 'react' export type BlockType = 'agent' | 'api' | 'conditional' export type BlockIcon = (props: SVGProps) => 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 {