Clean automationcreation

This commit is contained in:
Connor Yoh 2025-08-19 14:35:18 +01:00
parent 6ea300ddd3
commit 58e2a50b74

View File

@ -2,28 +2,24 @@ import React, { useState, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import {
Button,
Card,
Text,
Title,
Stack,
Group,
Select,
TextInput,
Textarea,
Badge,
ActionIcon,
Modal,
Box
Divider
} from '@mantine/core';
import AddIcon from '@mui/icons-material/Add';
import DeleteIcon from '@mui/icons-material/Delete';
import SettingsIcon from '@mui/icons-material/Settings';
import ArrowForwardIcon from '@mui/icons-material/ArrowForward';
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
import CheckIcon from '@mui/icons-material/Check';
import CloseIcon from '@mui/icons-material/Close';
import { useToolWorkflow } from '../../../contexts/ToolWorkflowContext';
import ToolConfigurationModal from './ToolConfigurationModal';
import AutomationEntry from './AutomationEntry';
interface AutomationCreationProps {
mode: 'custom' | 'suggested' | 'create';
@ -45,7 +41,6 @@ export default function AutomationCreation({ mode, existingAutomation, onBack, o
const { toolRegistry } = useToolWorkflow();
const [automationName, setAutomationName] = useState('');
const [automationDescription, setAutomationDescription] = useState('');
const [selectedTools, setSelectedTools] = useState<AutomationTool[]>([]);
const [configModalOpen, setConfigModalOpen] = useState(false);
const [configuraingToolIndex, setConfiguringToolIndex] = useState(-1);
@ -54,7 +49,6 @@ export default function AutomationCreation({ mode, existingAutomation, onBack, o
useEffect(() => {
if (mode === 'suggested' && existingAutomation) {
setAutomationName(existingAutomation.name);
setAutomationDescription(existingAutomation.description || '');
const tools = existingAutomation.operations.map((op: string) => ({
id: `${op}-${Date.now()}`,
@ -77,7 +71,7 @@ export default function AutomationCreation({ mode, existingAutomation, onBack, o
if (!toolRegistry) return [];
return Object.entries(toolRegistry)
.filter(([key]) => key !== 'automate') // Don't allow recursive automations
.filter(([key]) => key !== 'automate')
.map(([key, tool]) => ({
value: key,
label: (tool as any).name
@ -139,7 +133,7 @@ export default function AutomationCreation({ mode, existingAutomation, onBack, o
const automation = {
name: automationName.trim(),
description: automationDescription.trim(),
description: '',
operations: selectedTools.map(tool => ({
operation: tool.operation,
parameters: tool.parameters
@ -152,147 +146,108 @@ export default function AutomationCreation({ mode, existingAutomation, onBack, o
onComplete();
} catch (error) {
console.error('Error saving automation:', error);
// TODO: Show error notification to user
}
};
const currentConfigTool = configuraingToolIndex >= 0 ? selectedTools[configuraingToolIndex] : null;
return (
<Stack gap="xl">
<Group justify="space-between" align="center">
<div>
<Title order={2} mb="xs">
{mode === 'create'
? t('automate.creation.title.create', 'Create New Automation')
: mode === 'suggested'
? t('automate.creation.title.configure', 'Configure Automation')
: t('automate.creation.title.edit', 'Edit Automation')
}
</Title>
<Text size="sm" c="dimmed">
{t('automate.creation.description', 'Add and configure tools to create your workflow')}
</Text>
</div>
<Button
leftSection={<ArrowBackIcon />}
variant="light"
onClick={onBack}
>
{t('automate.creation.back', 'Back')}
</Button>
<div>
<Group justify="space-between" align="center" mb="md">
<Title order={3} size="h4" fw={600} style={{ color: 'var(--mantine-color-text)' }}>
{mode === 'create'
? t('automate.creation.title.create', 'Create Automation')
: t('automate.creation.title.configure', 'Configure Automation')
}
</Title>
<ActionIcon variant="subtle" onClick={onBack}>
<ArrowBackIcon />
</ActionIcon>
</Group>
{/* Automation Details */}
<Card shadow="sm" padding="md" radius="md" withBorder>
<Stack gap="md">
<TextInput
label={t('automate.creation.name.label', 'Automation Name')}
placeholder={t('automate.creation.name.placeholder', 'Enter a name for this automation')}
value={automationName}
onChange={(e) => setAutomationName(e.currentTarget.value)}
required
/>
<Textarea
label={t('automate.creation.description.label', 'Description')}
placeholder={t('automate.creation.description.placeholder', 'Optional description of what this automation does')}
value={automationDescription}
onChange={(e) => setAutomationDescription(e.currentTarget.value)}
minRows={2}
/>
</Stack>
</Card>
<Stack gap="md">
{/* Automation Name */}
<TextInput
placeholder={t('automate.creation.name.placeholder', 'Automation name')}
value={automationName}
onChange={(e) => setAutomationName(e.currentTarget.value)}
size="sm"
/>
{/* Tool Selection */}
<Card shadow="sm" padding="md" radius="md" withBorder>
<Group justify="space-between" align="center" mb="md">
<Text fw={600}>
{t('automate.creation.tools.title', 'Tools in Workflow')}
</Text>
<Select
placeholder={t('automate.creation.tools.add', 'Add a tool...')}
data={getAvailableTools()}
searchable
clearable
value={null}
onChange={addTool}
leftSection={<AddIcon />}
/>
</Group>
{/* Add Tool Selector */}
<Select
placeholder={t('automate.creation.tools.add', 'Add a tool...')}
data={getAvailableTools()}
searchable
clearable
value={null}
onChange={addTool}
leftSection={<AddIcon />}
size="sm"
/>
{selectedTools.length === 0 ? (
<Text size="sm" c="dimmed" ta="center" py="md">
{t('automate.creation.tools.empty', 'No tools added yet. Select a tool from the dropdown above.')}
</Text>
) : (
<Stack gap="sm">
{/* Selected Tools */}
{selectedTools.length > 0 && (
<Stack gap="xs">
{selectedTools.map((tool, index) => (
<Box key={tool.id}>
<Group gap="sm" align="center">
<Badge size="sm" variant="light">
{index + 1}
</Badge>
<Card
shadow="xs"
padding="sm"
radius="sm"
withBorder
style={{ flex: 1 }}
>
<Group justify="space-between" align="center">
<div>
<Group gap="xs" align="center">
<Text fw={500}>{tool.name}</Text>
{tool.configured ? (
<Badge size="xs" color="green" leftSection={<CheckIcon style={{ fontSize: 10 }} />}>
{t('automate.creation.tools.configured', 'Configured')}
</Badge>
) : (
<Badge size="xs" color="orange" leftSection={<CloseIcon style={{ fontSize: 10 }} />}>
{t('automate.creation.tools.needsConfig', 'Needs Configuration')}
</Badge>
)}
</Group>
</div>
<Group gap="xs">
<ActionIcon
variant="light"
onClick={() => configureTool(index)}
title={t('automate.creation.tools.configure', 'Configure')}
>
<SettingsIcon />
</ActionIcon>
<ActionIcon
variant="light"
color="red"
onClick={() => removeTool(index)}
title={t('automate.creation.tools.remove', 'Remove')}
>
<DeleteIcon />
</ActionIcon>
</Group>
<Group key={tool.id} gap="xs" align="center">
<Text size="xs" c="dimmed" style={{ minWidth: '1rem', textAlign: 'center' }}>
{index + 1}
</Text>
<div style={{ flex: 1 }}>
<Group justify="space-between" align="center">
<Group gap="xs" align="center">
<Text size="sm" style={{ color: 'var(--mantine-color-text)' }}>
{tool.name}
</Text>
{tool.configured ? (
<CheckIcon style={{ fontSize: 14, color: 'green' }} />
) : (
<CloseIcon style={{ fontSize: 14, color: 'orange' }} />
)}
</Group>
</Card>
{index < selectedTools.length - 1 && (
<ArrowForwardIcon style={{ color: 'var(--mantine-color-dimmed)' }} />
)}
</Group>
</Box>
<Group gap="xs">
<ActionIcon
variant="subtle"
size="sm"
onClick={() => configureTool(index)}
>
<SettingsIcon style={{ fontSize: 16 }} />
</ActionIcon>
<ActionIcon
variant="subtle"
size="sm"
color="red"
onClick={() => removeTool(index)}
>
<DeleteIcon style={{ fontSize: 16 }} />
</ActionIcon>
</Group>
</Group>
</div>
{index < selectedTools.length - 1 && (
<Text size="xs" c="dimmed"></Text>
)}
</Group>
))}
</Stack>
)}
</Card>
{/* Save Button */}
<Group justify="flex-end">
<Divider />
{/* Save Button */}
<Button
leftSection={<CheckIcon />}
onClick={saveAutomation}
disabled={!canSaveAutomation()}
fullWidth
>
{t('automate.creation.save', 'Save Automation')}
</Button>
</Group>
</Stack>
{/* Tool Configuration Modal */}
{currentConfigTool && (
@ -303,6 +258,6 @@ export default function AutomationCreation({ mode, existingAutomation, onBack, o
onCancel={handleToolConfigCancel}
/>
)}
</Stack>
</div>
);
}