Files
skybridge/faas/web/src/components/FunctionList.tsx
2025-09-01 13:10:35 -04:00

125 lines
2.9 KiB
TypeScript

import React, { useEffect, useState } from 'react';
import {
DataTable,
TableColumn,
Badge,
Group,
Text,
Stack
} from '@skybridge/web-components';
import {
IconPlayerPlay,
IconCode,
} from '@tabler/icons-react';
import { functionApi } from '../services/apiService';
import { FunctionDefinition } from '../types';
interface FunctionListProps {
onCreateFunction: () => void;
onEditFunction: (func: FunctionDefinition) => void;
onExecuteFunction: (func: FunctionDefinition) => void;
}
export const FunctionList: React.FC<FunctionListProps> = ({
onCreateFunction,
onEditFunction,
onExecuteFunction,
}) => {
const [functions, setFunctions] = useState<FunctionDefinition[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const loadFunctions = async () => {
try {
setLoading(true);
setError(null);
const data = await functionApi.listFunctions();
setFunctions(data);
} catch (error) {
console.error('Failed to load functions:', error);
setError('Failed to load functions');
} finally {
setLoading(false);
}
};
useEffect(() => {
loadFunctions();
}, []);
const handleDelete = async (func: FunctionDefinition) => {
await functionApi.deleteFunction(func.id);
loadFunctions();
};
const getStatusColor = (status: string) => {
switch (status) {
case 'active': return 'green';
case 'inactive': return 'gray';
case 'error': return 'red';
case 'building': return 'yellow';
default: return 'blue';
}
};
const columns: TableColumn[] = [
{
key: 'name',
label: 'Function Name',
sortable: true,
render: (value, func: FunctionDefinition) => (
<Group gap="xs">
<IconCode size={16} />
<Text fw={500}>{value}</Text>
</Group>
)
},
{
key: 'runtime',
label: 'Runtime',
render: (value) => (
<Badge variant="light" size="sm">{value}</Badge>
)
},
{
key: 'status',
label: 'Status',
render: (value) => (
<Badge color={getStatusColor(value)} size="sm">{value}</Badge>
)
},
{
key: 'created_at',
label: 'Created',
render: (value) => new Date(value).toLocaleDateString()
},
];
const customActions = [
{
key: 'execute',
label: 'Execute',
icon: <IconPlayerPlay size={14} />,
onClick: (func: FunctionDefinition) => onExecuteFunction(func),
},
];
return (
<Stack gap="md">
<DataTable
data={functions}
columns={columns}
loading={loading}
error={error}
title="Functions"
searchable
onAdd={onCreateFunction}
onEdit={onEditFunction}
onDelete={handleDelete}
onRefresh={loadFunctions}
customActions={customActions}
emptyMessage="No functions found"
/>
</Stack>
);
};