Faas semi worfking
This commit is contained in:
@ -8,7 +8,7 @@ import { ExecutionModal } from './components/ExecutionModal';
|
||||
import { FunctionDefinition } from './types';
|
||||
|
||||
// Default Mantine theme
|
||||
const theme = {
|
||||
const theme: any = {
|
||||
colorScheme: 'light',
|
||||
};
|
||||
|
||||
@ -20,6 +20,7 @@ const App: React.FC = () => {
|
||||
const [refreshKey, setRefreshKey] = useState(0);
|
||||
|
||||
const handleCreateFunction = () => {
|
||||
console.log('handleCreateFunction called');
|
||||
setEditingFunction(null);
|
||||
setFunctionFormOpened(true);
|
||||
};
|
||||
@ -94,4 +95,4 @@ const App: React.FC = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
||||
export default App;
|
||||
|
||||
@ -16,7 +16,7 @@ import {
|
||||
ActionIcon,
|
||||
Tooltip,
|
||||
} from '@mantine/core';
|
||||
import { IconPlay, IconPlayerStop, IconRefresh, IconCopy } from '@tabler/icons-react';
|
||||
import { IconPlayerPlay, IconPlayerStop, IconRefresh, IconCopy } from '@tabler/icons-react';
|
||||
import { notifications } from '@mantine/notifications';
|
||||
import { functionApi, executionApi } from '../services/api';
|
||||
import { FunctionDefinition, ExecuteFunctionResponse, FunctionExecution } from '../types';
|
||||
@ -209,7 +209,7 @@ export const ExecutionModal: React.FC<ExecutionModalProps> = ({
|
||||
/>
|
||||
<Group>
|
||||
<Button
|
||||
leftSection={<IconPlay size={16} />}
|
||||
leftSection={<IconPlayerPlay size={16} />}
|
||||
onClick={handleExecute}
|
||||
loading={executing}
|
||||
disabled={executing}
|
||||
@ -320,4 +320,4 @@ export const ExecutionModal: React.FC<ExecutionModalProps> = ({
|
||||
</Stack>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
@ -15,7 +15,7 @@ import {
|
||||
} from '@mantine/core';
|
||||
import { useForm } from '@mantine/form';
|
||||
import { notifications } from '@mantine/notifications';
|
||||
import { functionApi } from '../services/api';
|
||||
import { functionApi, runtimeApi } from '../services/api';
|
||||
import { FunctionDefinition, CreateFunctionRequest, UpdateFunctionRequest, RuntimeType } from '../types';
|
||||
|
||||
interface FunctionFormProps {
|
||||
@ -25,7 +25,6 @@ interface FunctionFormProps {
|
||||
editFunction?: FunctionDefinition;
|
||||
}
|
||||
|
||||
|
||||
export const FunctionForm: React.FC<FunctionFormProps> = ({
|
||||
opened,
|
||||
onClose,
|
||||
@ -34,14 +33,20 @@ export const FunctionForm: React.FC<FunctionFormProps> = ({
|
||||
}) => {
|
||||
const isEditing = !!editFunction;
|
||||
const [runtimeOptions, setRuntimeOptions] = useState<Array<{value: string; label: string}>>([]);
|
||||
|
||||
// Default images for each runtime
|
||||
const DEFAULT_IMAGES: Record<string, string> = {
|
||||
'nodejs18': 'node:18-alpine',
|
||||
'python3.9': 'python:3.9-alpine',
|
||||
'go1.20': 'golang:1.20-alpine',
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
// Fetch available runtimes from backend
|
||||
const fetchRuntimes = async () => {
|
||||
try {
|
||||
const response = await fetch('http://localhost:8083/api/runtimes');
|
||||
const data = await response.json();
|
||||
setRuntimeOptions(data.runtimes || []);
|
||||
const response = await runtimeApi.getRuntimes();
|
||||
setRuntimeOptions(response.data.runtimes || []);
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch runtimes:', error);
|
||||
// Fallback to default options
|
||||
@ -63,7 +68,7 @@ export const FunctionForm: React.FC<FunctionFormProps> = ({
|
||||
name: editFunction?.name || '',
|
||||
app_id: editFunction?.app_id || 'default',
|
||||
runtime: editFunction?.runtime || 'nodejs18' as RuntimeType,
|
||||
image: editFunction?.image || '',
|
||||
image: editFunction?.image || DEFAULT_IMAGES['nodejs18'] || '',
|
||||
handler: editFunction?.handler || 'index.handler',
|
||||
code: editFunction?.code || '',
|
||||
environment: editFunction?.environment ? JSON.stringify(editFunction.environment, null, 2) : '{}',
|
||||
@ -87,19 +92,35 @@ export const FunctionForm: React.FC<FunctionFormProps> = ({
|
||||
});
|
||||
|
||||
const handleRuntimeChange = (runtime: string | null) => {
|
||||
// if (runtime && DEFAULT_IMAGES[runtime]) {
|
||||
// form.setFieldValue('image', DEFAULT_IMAGES[runtime]);
|
||||
// }
|
||||
if (runtime && DEFAULT_IMAGES[runtime]) {
|
||||
form.setFieldValue('image', DEFAULT_IMAGES[runtime]);
|
||||
}
|
||||
form.setFieldValue('runtime', runtime as RuntimeType);
|
||||
};
|
||||
|
||||
const handleSubmit = async (values: typeof form.values) => {
|
||||
console.log('handleSubmit called with values:', values);
|
||||
console.log('Form validation errors:', form.errors);
|
||||
console.log('Is form valid?', form.isValid());
|
||||
|
||||
// Check each field individually
|
||||
const fieldNames = ['name', 'app_id', 'runtime', 'image', 'handler', 'timeout', 'memory'];
|
||||
fieldNames.forEach(field => {
|
||||
const error = form.validateField(field);
|
||||
console.log(`Field ${field} error:`, error);
|
||||
});
|
||||
|
||||
if (!form.isValid()) {
|
||||
console.log('Form is not valid, validation errors:', form.errors);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
// Parse environment variables JSON
|
||||
let parsedEnvironment;
|
||||
try {
|
||||
parsedEnvironment = values.environment ? JSON.parse(values.environment) : undefined;
|
||||
} catch (error) {
|
||||
console.error('Error parsing environment variables:', error);
|
||||
notifications.show({
|
||||
title: 'Error',
|
||||
message: 'Invalid JSON in environment variables',
|
||||
@ -165,7 +186,15 @@ export const FunctionForm: React.FC<FunctionFormProps> = ({
|
||||
title={isEditing ? 'Edit Function' : 'Create Function'}
|
||||
size="lg"
|
||||
>
|
||||
<form onSubmit={form.onSubmit(handleSubmit)}>
|
||||
<form onSubmit={(e) => {
|
||||
console.log('Form submit event triggered');
|
||||
console.log('Form values:', form.values);
|
||||
console.log('Form errors:', form.errors);
|
||||
console.log('Is form valid?', form.isValid());
|
||||
const result = form.onSubmit(handleSubmit)(e);
|
||||
console.log('Form onSubmit result:', result);
|
||||
return result;
|
||||
}}>
|
||||
<Stack gap="md">
|
||||
<Group grow>
|
||||
<TextInput
|
||||
@ -296,4 +325,4 @@ def handler(event, context):
|
||||
</form>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
@ -15,7 +15,7 @@ import {
|
||||
Tooltip,
|
||||
} from '@mantine/core';
|
||||
import {
|
||||
IconPlay,
|
||||
IconPlayerPlay,
|
||||
IconSettings,
|
||||
IconTrash,
|
||||
IconRocket,
|
||||
@ -49,7 +49,9 @@ export const FunctionList: React.FC<FunctionListProps> = ({
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
const response = await functionApi.list();
|
||||
setFunctions(response.data.functions || []);
|
||||
// Ensure we have a valid array
|
||||
const functionsArray = response.data?.functions || [];
|
||||
setFunctions(functionsArray);
|
||||
} catch (err) {
|
||||
console.error('Failed to load functions:', err);
|
||||
setError('Failed to load functions');
|
||||
@ -210,13 +212,15 @@ export const FunctionList: React.FC<FunctionListProps> = ({
|
||||
</Table.Td>
|
||||
<Table.Td>
|
||||
<Text size="sm">
|
||||
{func.owner.name}
|
||||
<Text size="xs" c="dimmed">({func.owner.type})</Text>
|
||||
{func.owner?.name || 'Unknown'}
|
||||
{func.owner?.type && (
|
||||
<Text size="xs" c="dimmed">({func.owner.type})</Text>
|
||||
)}
|
||||
</Text>
|
||||
</Table.Td>
|
||||
<Table.Td>
|
||||
<Text size="sm">
|
||||
{new Date(func.created_at).toLocaleDateString()}
|
||||
{func.created_at ? new Date(func.created_at).toLocaleDateString() : 'N/A'}
|
||||
</Text>
|
||||
</Table.Td>
|
||||
<Table.Td>
|
||||
@ -228,7 +232,7 @@ export const FunctionList: React.FC<FunctionListProps> = ({
|
||||
size="sm"
|
||||
onClick={() => onExecuteFunction(func)}
|
||||
>
|
||||
<IconPlay size={16} />
|
||||
<IconPlayerPlay size={16} />
|
||||
</ActionIcon>
|
||||
</Tooltip>
|
||||
<Menu position="bottom-end">
|
||||
@ -268,4 +272,4 @@ export const FunctionList: React.FC<FunctionListProps> = ({
|
||||
)}
|
||||
</Paper>
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
@ -37,8 +37,10 @@ export const functionApi = {
|
||||
params: { app_id: appId, limit, offset },
|
||||
}),
|
||||
|
||||
create: (data: CreateFunctionRequest) =>
|
||||
api.post<FunctionDefinition>('/functions', data),
|
||||
create: (data: CreateFunctionRequest) => {
|
||||
console.log('Making API call to create function with data:', data);
|
||||
return api.post<FunctionDefinition>('/functions', data);
|
||||
},
|
||||
|
||||
getById: (id: string) =>
|
||||
api.get<FunctionDefinition>(`/functions/${id}`),
|
||||
@ -85,4 +87,6 @@ export const healthApi = {
|
||||
ready: () => api.get('/ready'),
|
||||
};
|
||||
|
||||
export default api;
|
||||
export const runtimeApi = {
|
||||
getRuntimes: () => api.get('/runtimes'),
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user