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