import {useEffect, useState} from 'react' import {Loader2, Plus, RefreshCw, Trash2} from 'lucide-react' import {useMutation, useQuery, useQueryClient} from '@tanstack/react-query' import {createLambdaEventSourceMapping, deleteLambdaEventSourceMapping, listCloudResources, listKinesisRecords, listLambdaEventSourceMappings, putKinesisRecord, updateLambdaEventSourceMapping, type LambdaEventSourceMappingOverview} from '@/api/cloudProxyClient' import type {CloudProvider} from '@/types/cloud' import type {CloudResource} from '@/types/resource' interface KinesisPanelProps {cloud: CloudProvider; resource?: CloudResource; runtimeReachable: boolean; mode: 'stream' | 'lambda'} export function KinesisPanel({cloud, resource, runtimeReachable, mode}: KinesisPanelProps) { const queryClient = useQueryClient() const [partitionKey, setPartitionKey] = useState('console') const [data, setData] = useState('{}') const [functionName, setFunctionName] = useState('') const [streamArn, setStreamArn] = useState('') const [batchSize, setBatchSize] = useState('100') const [startingPosition, setStartingPosition] = useState<'TRIM_HORIZON' | 'LATEST'>('LATEST') const [deleteTarget, setDeleteTarget] = useState(null) const streamsQuery = useQuery({queryKey: ['cloud-resources', cloud, 'kinesis'], queryFn: ({signal}) => listCloudResources(cloud, 'kinesis', undefined, signal), enabled: mode === 'lambda' && cloud === 'aws' && runtimeReachable}) const functionsQuery = useQuery({queryKey: ['cloud-resources', cloud, 'serverless'], queryFn: ({signal}) => listCloudResources(cloud, 'serverless', undefined, signal), enabled: mode === 'stream' && cloud === 'aws' && runtimeReachable}) const streamName = mode === 'stream' ? resource?.id : undefined const sourceArn = mode === 'stream' ? resource?.metadata.arn as string | undefined : streamArn const lambdaName = mode === 'lambda' ? resource?.name : functionName const recordsQuery = useQuery({queryKey: ['kinesis-records', cloud, streamName], queryFn: ({signal}) => listKinesisRecords(cloud, streamName!, signal), enabled: mode === 'stream' && Boolean(streamName) && runtimeReachable}) const mappingsQuery = useQuery({queryKey: ['kinesis-lambda-mappings', cloud, sourceArn, lambdaName], queryFn: ({signal}) => listLambdaEventSourceMappings(cloud, mode === 'stream' ? {eventSourceArn: sourceArn} : {functionName: lambdaName}, signal), enabled: Boolean(sourceArn || lambdaName) && runtimeReachable}) useEffect(() => { setFunctionName(''); setStreamArn(''); setDeleteTarget(null) }, [resource?.id]) const putMutation = useMutation({mutationFn: () => putKinesisRecord(cloud, streamName!, {partitionKey, data}), onSuccess: () => queryClient.invalidateQueries({queryKey: ['kinesis-records', cloud, streamName]})}) const createMutation = useMutation({mutationFn: () => createLambdaEventSourceMapping(cloud, {functionName: lambdaName!, eventSourceArn: sourceArn!, batchSize: Number(batchSize), startingPosition}), onSuccess: () => queryClient.invalidateQueries({queryKey: ['kinesis-lambda-mappings']})}) const updateMutation = useMutation({mutationFn: ({id, enabled}: {id: string; enabled: boolean}) => updateLambdaEventSourceMapping(cloud, id, {enabled}), onSuccess: () => queryClient.invalidateQueries({queryKey: ['kinesis-lambda-mappings']})}) const deleteMutation = useMutation({mutationFn: (id: string) => deleteLambdaEventSourceMapping(cloud, id), onSuccess: () => { setDeleteTarget(null); queryClient.invalidateQueries({queryKey: ['kinesis-lambda-mappings']}) }}) if (!resource || (mode === 'stream' && resource.service !== 'kinesis') || (mode === 'lambda' && resource.type !== 'lambda')) return null const canCreate = Boolean(lambdaName && sourceArn) && Number.isInteger(Number(batchSize)) && Number(batchSize) >= 1 && Number(batchSize) <= 10_000 const mappings = (mappingsQuery.data ?? []).filter((mapping) => mapping.eventSourceArn.includes(':kinesis:')) return
{mode === 'stream' && <>

Records

Produce records

{ event.preventDefault(); putMutation.mutate() }}>