125 lines
2.9 KiB
TypeScript
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>
|
|
);
|
|
}; |