/** * AutomationsPage * * Page for viewing and managing workflow automations using FormGeneratorTable. * Follows the pattern established in AdminUsersPage/WorkflowsPage. */ import React, { useState, useMemo, useEffect } from 'react'; import { useAutomations, useAutomationOperations } from '../../hooks/useAutomations'; import { FormGeneratorTable } from '../../components/FormGenerator/FormGeneratorTable'; import { FormGeneratorForm } from '../../components/FormGenerator/FormGeneratorForm'; import { FaSync, FaRobot, FaPlay, FaPlus, FaToggleOn, FaToggleOff } from 'react-icons/fa'; import styles from '../admin/Admin.module.css'; interface Automation { id: string; label: string; schedule?: string; active: boolean; status?: string; template?: string; placeholders?: any; [key: string]: any; } export const AutomationsPage: React.FC = () => { // Data hook const { data: automations, attributes, permissions, pagination, loading, error, refetch, fetchAutomationById, updateOptimistically, } = useAutomations(); // Operations hook const { handleAutomationCreate, handleAutomationUpdate, handleAutomationDelete, handleAutomationExecute, handleAutomationToggleActive, handleInlineUpdate, deletingAutomations, executingAutomations, creatingAutomation, } = useAutomationOperations(); const [showCreateModal, setShowCreateModal] = useState(false); const [editingAutomation, setEditingAutomation] = useState(null); // Initial fetch useEffect(() => { refetch(); }, []); // Generate columns from attributes const columns = useMemo(() => { return (attributes || []).map(attr => ({ key: attr.name, label: attr.label || attr.name, type: attr.type as any, sortable: attr.sortable !== false, filterable: attr.filterable !== false, searchable: attr.searchable !== false, width: attr.width || 150, minWidth: attr.minWidth || 100, maxWidth: attr.maxWidth || 400, })); }, [attributes]); // Check permissions const canCreate = permissions?.create !== 'n'; const canUpdate = permissions?.update !== 'n'; const canDelete = permissions?.delete !== 'n'; // Handle edit click const handleEditClick = async (automation: Automation) => { const fullAutomation = await fetchAutomationById(automation.id); if (fullAutomation) { setEditingAutomation(fullAutomation as Automation); } }; // Handle create submit const handleCreateSubmit = async (data: Partial) => { const result = await handleAutomationCreate(data as any); if (result) { setShowCreateModal(false); refetch(); } }; // Handle edit submit const handleEditSubmit = async (data: Partial) => { if (!editingAutomation) return; const success = await handleAutomationUpdate(editingAutomation.id, data); if (success) { setEditingAutomation(null); refetch(); } }; // Handle delete single automation const handleDelete = async (automation: Automation) => { if (window.confirm(`Möchten Sie die Automatisierung "${automation.label}" wirklich löschen?`)) { const success = await handleAutomationDelete(automation.id); if (success) { refetch(); } } }; // Handle execute automation const handleExecute = async (automation: Automation) => { try { await handleAutomationExecute(automation.id); // Show success feedback (could use toast) console.log('Automation started:', automation.label); } catch (err: any) { console.error('Error executing automation:', err); } }; // Handle toggle active const handleToggleActive = async (automation: Automation) => { // Optimistic update updateOptimistically(automation.id, { active: !automation.active }); const success = await handleAutomationToggleActive(automation.id, automation.active); if (!success) { // Revert on failure updateOptimistically(automation.id, { active: automation.active }); } }; // Form attributes for create/edit modal const formAttributes = useMemo(() => { const excludedFields = ['id', 'mandateId', '_createdBy', '_createdAt', '_modifiedAt', 'status']; return (attributes || []) .filter(attr => !excludedFields.includes(attr.name)); }, [attributes]); if (error) { return (
⚠️

Fehler beim Laden der Automatisierungen: {error}

); } return (

Automatisierungen

Geplante und automatisierte Workflows

{canCreate && ( )}
{loading && (!automations || automations.length === 0) ? (
Lade Automatisierungen...
) : !automations || automations.length === 0 ? (

Keine Automatisierungen vorhanden

Erstellen Sie eine neue Automatisierung, um Workflows zeitgesteuert auszuführen.

{canCreate && ( )}
) : ( deletingAutomations.has(row.id), }] : []), ]} customActions={[ { id: 'execute', icon: , onClick: handleExecute, title: 'Ausführen', loading: (row: Automation) => executingAutomations.has(row.id), }, { id: 'toggleActive', icon: (row: Automation) => row.active ? : , onClick: handleToggleActive, title: (row: Automation) => row.active ? 'Deaktivieren' : 'Aktivieren', } as any, ]} onDelete={handleDelete} hookData={{ refetch, permissions, pagination, handleDelete: handleAutomationDelete, handleInlineUpdate, updateOptimistically, }} emptyMessage="Keine Automatisierungen gefunden" /> )}
{/* Create Modal */} {showCreateModal && (
setShowCreateModal(false)}>
e.stopPropagation()}>

Neue Automatisierung

{formAttributes.length === 0 ? (
Lade Formular...
) : ( setShowCreateModal(false)} submitButtonText="Erstellen" cancelButtonText="Abbrechen" /> )}
)} {/* Edit Modal */} {editingAutomation && (
setEditingAutomation(null)}>
e.stopPropagation()}>

Automatisierung bearbeiten

{formAttributes.length === 0 ? (
Lade Formular...
) : ( setEditingAutomation(null)} submitButtonText="Speichern" cancelButtonText="Abbrechen" /> )}
)}
); }; export default AutomationsPage;