import { useCallback } from 'react'; import { GenericPageData } from '../../pageInterface'; import { FaCog, FaPlus } from 'react-icons/fa'; import { useAutomations, useAutomationOperations } from '../../../../hooks/useAutomations'; // Helper function to convert attribute definitions to column config const attributesToColumns = (attributes: any[]) => { return attributes .filter(attr => { // Exclude template and complex fields from table display const attrNameLower = attr.name.toLowerCase(); const excludedColumns = ['template', 'executionlogs', 'execution_logs']; return !excludedColumns.includes(attrNameLower); }) .map(attr => { const attrNameLower = attr.name.toLowerCase(); const isDateField = attr.type === 'date' || /(date|Date|timestamp|Timestamp|created|Created|updated|Updated|at|At)$/i.test(attr.name); const column: any = { key: attr.name, label: attr.label || attr.name, type: attr.type || 'string', width: attr.width || 200, minWidth: attr.minWidth || 100, maxWidth: attr.maxWidth || 400, sortable: attr.sortable !== false, filterable: isDateField ? false : (attr.filterable !== false), searchable: attr.searchable !== false, filterOptions: attr.filterOptions }; // Format schedule field if (attrNameLower === 'schedule') { column.formatter = (value: any) => { if (!value) return '-'; const scheduleLabels: Record = { '0 */4 * * *': 'Every 4 hours', '0 22 * * *': 'Daily at 22:00', '0 10 * * 1': 'Weekly Monday 10:00' }; return scheduleLabels[value] || value; }; } // Format active field as badge if (attrNameLower === 'active') { column.type = 'boolean'; } // Format placeholders as count if (attrNameLower === 'placeholders') { column.formatter = (value: any) => { if (!value) return '-'; let obj; if (typeof value === 'string') { try { obj = JSON.parse(value); } catch { return '-'; } } else if (typeof value === 'object') { obj = value; } else { return '-'; } const count = Object.keys(obj).length; return `${count} placeholder${count !== 1 ? 's' : ''}`; }; } return column; }); }; // Hook factory function for automations data const createAutomationsHook = () => { return () => { const { automations, loading, error, refetch, removeOptimistically, updateOptimistically, attributes, permissions, pagination, fetchAutomationById, generateEditFieldsFromAttributes, generateCreateFieldsFromAttributes, ensureAttributesLoaded } = useAutomations(); const { handleAutomationDelete, handleAutomationCreate, handleAutomationUpdate, handleAutomationExecute, handleAutomationToggleActive, deletingAutomations, creatingAutomation, executingAutomations, deleteError, createError, updateError } = useAutomationOperations(); const generatedColumns = attributes && attributes.length > 0 ? attributesToColumns(attributes) : undefined; // Handle single automation deletion const handleDeleteSingle = useCallback(async (automation: any) => { const success = await handleAutomationDelete(automation.id); if (success) { refetch(); } }, [handleAutomationDelete, refetch]); // Handle multiple automation deletion const handleDeleteMultiple = useCallback(async (selectedAutomations: any[]) => { const results = await Promise.all( selectedAutomations.map(a => handleAutomationDelete(a.id)) ); const allSuccessful = results.every(result => result); if (allSuccessful) { refetch(); } }, [handleAutomationDelete, refetch]); // Wrapped create handler const wrappedHandleAutomationCreate = useCallback(async (formData: any) => { return await handleAutomationCreate(formData); }, [handleAutomationCreate]); return { data: automations, loading, error, refetch, removeOptimistically, updateOptimistically, // Operations handleDelete: handleAutomationDelete, handleDeleteMultiple, handleAutomationCreate: wrappedHandleAutomationCreate, handleAutomationUpdate, handleAutomationExecute, handleAutomationToggleActive, // FormGenerator specific handlers onDelete: handleDeleteSingle, onDeleteMultiple: handleDeleteMultiple, // Loading states deletingAutomations, creatingAutomation, executingAutomations, // Error states deleteError, createError, updateError, // Attributes and permissions attributes, permissions, pagination, columns: generatedColumns, // Functions for EditActionButton fetchAutomationById, generateEditFieldsFromAttributes, generateCreateFieldsFromAttributes, ensureAttributesLoaded }; }; }; export const automationsPageData: GenericPageData = { id: 'workflows-automations', path: 'workflows/automations', name: 'automations.title', description: 'automations.description', // Parent page - under 'workflows' group parentPath: 'workflows', // Visual icon: FaCog, title: 'automations.title', subtitle: 'automations.subtitle', // Header buttons headerButtons: [ { id: 'new-automation', label: 'automations.new_button', icon: FaPlus, variant: 'primary', formConfig: { fields: [], // Fields will be generated dynamically from attributes popupTitle: 'automations.modal.create.title', popupSize: 'large', createOperationName: 'handleAutomationCreate', successMessage: 'automations.create.success', errorMessage: 'automations.create.error' } } ], // Content sections - using generic table approach content: [ { id: 'automations-table', type: 'table', tableConfig: { hookFactory: createAutomationsHook, // Columns are generated dynamically from attributes via hookData.columns actionButtons: [ { type: 'play', title: 'automations.action.execute', idField: 'id', operationName: 'handleAutomationExecute', loadingStateName: 'executingAutomations', disabled: (hookData: any) => { if (!hookData?.permissions) return { disabled: false }; const hasExecute = hookData.permissions.update !== 'n' && hookData.permissions.view; return { disabled: !hasExecute, message: 'No permission to execute automations' }; } }, { type: 'edit', title: 'automations.action.edit', idField: 'id', nameField: 'label', operationName: 'handleAutomationUpdate', loadingStateName: 'updatingAutomations', fetchItemFunctionName: 'fetchAutomationById', disabled: (hookData: any) => { if (!hookData?.permissions) return { disabled: false }; const hasUpdate = hookData.permissions.update !== 'n' && hookData.permissions.view; return { disabled: !hasUpdate, message: 'No permission to edit automations' }; } }, { type: 'delete', title: 'automations.action.delete', idField: 'id', operationName: 'handleDelete', loadingStateName: 'deletingAutomations', disabled: (hookData: any) => { if (!hookData?.permissions) return { disabled: false }; const hasDelete = hookData.permissions.delete !== 'n' && hookData.permissions.view; return { disabled: !hasDelete, message: 'No permission to delete automations' }; } } ], searchable: true, filterable: true, sortable: true, resizable: true, pagination: true, pageSize: 10, className: 'automations-table' } } ], // Page behavior persistent: false, preload: false, preserveState: true, moduleEnabled: true, // Lifecycle hooks onActivate: async () => { if (import.meta.env.DEV) console.log('Automations activated'); }, onLoad: async () => { if (import.meta.env.DEV) console.log('Automations loaded'); }, onUnload: async () => { if (import.meta.env.DEV) console.log('Automations unloaded'); } };