fix(ui): airtable block/tools

This commit is contained in:
Waleed Latif
2025-04-01 16:53:25 -07:00
parent 25e59ee695
commit 078f81f8bc
3 changed files with 33 additions and 107 deletions
-89
View File
@@ -1,89 +0,0 @@
/**
* @vitest-environment jsdom
*
* Airtable Block Integration Tests
*/
import { describe, expect, test } from 'vitest'
import { AirtableBlock } from './airtable'
describe('Airtable Block', () => {
test('should have correct configuration', () => {
expect(AirtableBlock.type).toBe('airtable')
expect(AirtableBlock.category).toBe('tools')
expect(AirtableBlock.tools.access).toContain('airtable_read')
expect(AirtableBlock.tools.access).toContain('airtable_write')
expect(AirtableBlock.tools.access).toContain('airtable_update')
})
test('should select correct tool based on operation', () => {
const config = AirtableBlock.tools.config
if (!config) {
throw new Error('Tool config is missing')
}
expect(config.tool({ operation: 'read' })).toBe('airtable_read')
expect(config.tool({ operation: 'write' })).toBe('airtable_write')
expect(config.tool({ operation: 'update' })).toBe('airtable_update')
expect(() => config.tool({ operation: 'invalid' })).toThrow('Invalid Airtable operation')
})
test('should transform parameters correctly', () => {
const config = AirtableBlock.tools.config
if (!config || !config.params) {
throw new Error('Tool config or params is missing')
}
// Test read operation
const readParams = config.params({
operation: 'read',
credential: 'oauth_token',
baseId: 'base123',
tableId: 'table456',
maxRecords: '100',
filterFormula: "Status='Active'"
})
expect(readParams.accessToken).toBe('oauth_token')
expect(readParams.baseId).toBe('base123')
expect(readParams.tableId).toBe('table456')
// Test write operation
const writeParams = config.params({
operation: 'write',
credential: 'oauth_token',
baseId: 'base123',
tableId: 'table456',
records: JSON.stringify([{ fields: { Name: 'Test' } }])
})
expect(writeParams.accessToken).toBe('oauth_token')
expect(writeParams.records).toEqual([{ fields: { Name: 'Test' } }])
// Test update operation
const updateParams = config.params({
operation: 'update',
credential: 'oauth_token',
baseId: 'base123',
tableId: 'table456',
recordId: 'rec789',
records: JSON.stringify({ fields: { Name: 'Updated' } })
})
expect(updateParams.accessToken).toBe('oauth_token')
expect(updateParams.recordId).toBe('rec789')
expect(updateParams.fields).toEqual({ fields: { Name: 'Updated' } })
})
test('should have required OAuth configuration', () => {
const subBlocks = AirtableBlock.subBlocks
const credentialBlock = subBlocks.find(block => block.id === 'credential')
expect(credentialBlock).toBeDefined()
expect(credentialBlock?.type).toBe('oauth-input')
expect(credentialBlock?.provider).toBe('airtable')
expect(credentialBlock?.requiredScopes).toContain('data.records:read')
expect(credentialBlock?.requiredScopes).toContain('data.records:write')
})
})
+7 -7
View File
@@ -1,8 +1,8 @@
import { AirtableIcon } from '@/components/icons'
import {
AirtableReadResponse,
AirtableWriteResponse,
AirtableUpdateResponse,
AirtableWriteResponse,
} from '@/tools/airtable/types'
import { BlockConfig } from '../types'
@@ -12,12 +12,12 @@ export const AirtableBlock: BlockConfig<AirtableResponse> = {
type: 'airtable',
name: 'Airtable',
description: 'Read, write, and update Airtable records',
longDescription:
longDescription:
'Integrate Airtable functionality to manage table records. Read data from existing tables, ' +
'write new records, and update existing ones using OAuth authentication. Supports table ' +
'selection and record operations with custom field mapping.',
category: 'tools',
bgColor: '#FCB400',
bgColor: '#E0E0E0',
icon: AirtableIcon,
subBlocks: [
// Operation selector
@@ -120,7 +120,7 @@ export const AirtableBlock: BlockConfig<AirtableResponse> = {
},
params: (params) => {
const { credential, records, ...rest } = params
if (params.operation === 'update' && records) {
const parsedRecords = JSON.parse(records)
return {
@@ -129,7 +129,7 @@ export const AirtableBlock: BlockConfig<AirtableResponse> = {
...rest,
}
}
return {
accessToken: credential,
records: records ? JSON.parse(records) : undefined,
@@ -147,8 +147,8 @@ export const AirtableBlock: BlockConfig<AirtableResponse> = {
maxRecords: { type: 'number', required: false },
filterFormula: { type: 'string', required: false },
// Write/Update operation inputs
records: {
type: 'json',
records: {
type: 'json',
required: false,
schema: {
type: 'object',
+26 -11
View File
@@ -1516,19 +1516,34 @@ export function RedditIcon(props: SVGProps<SVGSVGElement>) {
export function AirtableIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
{...props}
width="800px"
height="800px"
viewBox="0 -20.5 256 256"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
preserveAspectRatio="xMidYMid"
>
<path d="M4 9.5V4a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v5.5" />
<path d="M6.5 16.5v-4.25c0-.41.34-.75.75-.75h9.5c.41 0 .75.34.75.75v4.25" />
<path d="M3 16.5h18" />
<path d="M4 21h16a1 1 0 0 0 1-1v-3.5H3V20a1 1 0 0 0 1 1z" />
<rect x="7" y="8" width="10" height="3" rx="0.5" />
<g>
<path
d="M114.25873,2.70101695 L18.8604023,42.1756384 C13.5552723,44.3711638 13.6102328,51.9065311 18.9486282,54.0225085 L114.746142,92.0117514 C123.163769,95.3498757 132.537419,95.3498757 140.9536,92.0117514 L236.75256,54.0225085 C242.08951,51.9065311 242.145916,44.3711638 236.83934,42.1756384 L141.442459,2.70101695 C132.738459,-0.900338983 122.961284,-0.900338983 114.25873,2.70101695"
fill="#FFBF00"
></path>
<path
d="M136.349071,112.756863 L136.349071,207.659101 C136.349071,212.173089 140.900664,215.263892 145.096461,213.600615 L251.844122,172.166219 C254.281184,171.200072 255.879376,168.845451 255.879376,166.224705 L255.879376,71.3224678 C255.879376,66.8084791 251.327783,63.7176768 247.131986,65.3809537 L140.384325,106.815349 C137.94871,107.781496 136.349071,110.136118 136.349071,112.756863"
fill="#26B5F8"
></path>
<path
d="M111.422771,117.65355 L79.742409,132.949912 L76.5257763,134.504714 L9.65047684,166.548104 C5.4112904,168.593211 0.000578531073,165.503855 0.000578531073,160.794612 L0.000578531073,71.7210757 C0.000578531073,70.0173017 0.874160452,68.5463864 2.04568588,67.4384994 C2.53454463,66.9481944 3.08848814,66.5446689 3.66412655,66.2250305 C5.26231864,65.2661153 7.54173107,65.0101153 9.47981017,65.7766689 L110.890522,105.957098 C116.045234,108.002206 116.450206,115.225166 111.422771,117.65355"
fill="#ED3049"
></path>
<path
d="M111.422771,117.65355 L79.742409,132.949912 L2.04568588,67.4384994 C2.53454463,66.9481944 3.08848814,66.5446689 3.66412655,66.2250305 C5.26231864,65.2661153 7.54173107,65.0101153 9.47981017,65.7766689 L110.890522,105.957098 C116.045234,108.002206 116.450206,115.225166 111.422771,117.65355"
fill-opacity="0.25"
fill="#000000"
></path>
</g>
</svg>
)
}