mirror of
https://github.com/simstudioai/sim.git
synced 2026-09-24 15:45:35 +08:00
fix(ui): airtable block/tools
This commit is contained in:
@@ -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')
|
||||
})
|
||||
})
|
||||
@@ -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
@@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user