/** * AdminAutomationLogsPage * * SysAdmin-only page for viewing consolidated automation execution logs * across all mandates and feature instances. * Uses FormGeneratorTable with backend-driven pagination. */ import React, { useState, useEffect, useCallback, useMemo } from 'react'; import { FaSync, FaCheck, FaExclamationCircle, FaTimes } from 'react-icons/fa'; import api from '../../api'; import styles from './Admin.module.css'; import { FormGeneratorTable, type ColumnConfig } from '../../components/FormGenerator/FormGeneratorTable'; interface AutomationLogEntry { id: string; timestamp: number; automationId: string; automationLabel: string; mandateName: string; featureInstanceName: string; executedBy: string; status: string; workflowId: string; messages: string; } const _formatTimestamp = (ts: unknown): React.ReactNode => { if (!ts || typeof ts !== 'number') return ; return new Date(ts * 1000).toLocaleString('de-CH', { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit', second: '2-digit', }); }; const _formatStatus = (value: unknown): React.ReactNode => { const status = String(value || ''); const map: Record = { completed: { icon: , color: 'var(--success-color, #16a34a)', label: 'Abgeschlossen' }, error: { icon: , color: 'var(--error-color, #dc2626)', label: 'Fehler' }, failed: { icon: , color: 'var(--error-color, #dc2626)', label: 'Fehlgeschlagen' }, stopped: { icon: , color: 'var(--warning-color, #d97706)', label: 'Gestoppt' }, }; const entry = map[status]; if (!entry) return status || '–'; return ( {entry.icon}{entry.label} ); }; export const AdminAutomationLogsPage: React.FC = () => { const [logs, setLogs] = useState([]); const [pagination, setPagination] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const _fetchLogs = useCallback(async (params?: any) => { try { setLoading(true); setError(null); const requestParams: Record = {}; if (params && typeof params === 'object') { const paginationObj: any = {}; if (params.page !== undefined) paginationObj.page = params.page; if (params.pageSize !== undefined) paginationObj.pageSize = params.pageSize; if (params.sort) paginationObj.sort = params.sort; if (params.filters) paginationObj.filters = params.filters; if (params.search) paginationObj.search = params.search; if (Object.keys(paginationObj).length > 0) { requestParams.pagination = JSON.stringify(paginationObj); } } const response = await api.get('/api/admin/automation-logs', { params: requestParams }); const data = response.data; if (data && typeof data === 'object' && 'items' in data) { setLogs(data.items || []); if (data.pagination) setPagination(data.pagination); } else { setLogs(Array.isArray(data) ? data : []); setPagination(null); } } catch (err: any) { setError(err.response?.data?.detail || 'Fehler beim Laden der Ausführungsprotokolle'); } finally { setLoading(false); } }, []); useEffect(() => { _fetchLogs(); }, [_fetchLogs]); const columns: ColumnConfig[] = useMemo(() => [ { key: 'timestamp', label: 'Zeitpunkt', type: 'number' as const, sortable: true, filterable: false, width: 170, minWidth: 140, formatter: _formatTimestamp, }, { key: 'automationLabel', label: 'Automatisierung', type: 'string' as const, sortable: true, filterable: true, searchable: true, width: 200, minWidth: 130, }, { key: 'mandateName', label: 'Mandant', type: 'string' as const, sortable: true, filterable: true, width: 150, minWidth: 100, }, { key: 'featureInstanceName', label: 'Feature-Instanz', type: 'string' as const, sortable: true, filterable: true, width: 150, minWidth: 100, }, { key: 'executedBy', label: 'Ausgeführt von', type: 'string' as const, sortable: true, filterable: true, width: 140, minWidth: 100, }, { key: 'status', label: 'Status', type: 'string' as const, sortable: true, filterable: true, width: 140, minWidth: 100, formatter: _formatStatus, }, { key: 'workflowId', label: 'Workflow-ID', type: 'string' as const, sortable: false, filterable: false, width: 120, minWidth: 80, formatter: (v: unknown) => v ? {String(v).slice(0, 8)}… : '–', }, { key: 'messages', label: 'Meldungen', type: 'string' as const, sortable: false, filterable: false, searchable: true, width: 300, minWidth: 150, maxWidth: 500, }, ], []); return (

Ausführungsprotokolle

Konsolidierte Automation-Logs über alle Mandanten

{error && (
! {error}
)}
); }; export default AdminAutomationLogsPage;