import React, { useEffect, useState } from 'react'; import { fetchClientsWithoutDescription, setClientDescription } from './apiClients'; import { ButtonComponent } from '@syncfusion/ej2-react-buttons'; import { TextBoxComponent } from '@syncfusion/ej2-react-inputs'; import { GridComponent, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-grids'; import { DialogComponent } from '@syncfusion/ej2-react-popups'; import { useClientDelete } from './hooks/useClientDelete'; type Client = { uuid: string; hostname?: string; ip_address?: string; last_alive?: string; }; const SetupMode: React.FC = () => { const [clients, setClients] = useState([]); const [descriptions, setDescriptions] = useState>({}); const [loading /* setLoading */] = useState(false); const [inputActive, setInputActive] = useState(false); // Lösch-Logik aus Hook (analog zu clients.tsx) const { showDialog, deleteClientId, handleDelete, confirmDelete, cancelDelete } = useClientDelete( async uuid => { // Nach dem Löschen neu laden! const updated = await fetchClientsWithoutDescription(); setClients(updated); setDescriptions(prev => { const copy = { ...prev }; delete copy[uuid]; return copy; }); } ); // Hilfsfunktion zum Vergleich der Clients const isEqual = (a: Client[], b: Client[]) => { if (a.length !== b.length) return false; const aSorted = [...a].sort((x, y) => x.uuid.localeCompare(y.uuid)); const bSorted = [...b].sort((x, y) => x.uuid.localeCompare(y.uuid)); for (let i = 0; i < aSorted.length; i++) { if (aSorted[i].uuid !== bSorted[i].uuid) return false; if (aSorted[i].hostname !== bSorted[i].hostname) return false; if (aSorted[i].ip_address !== bSorted[i].ip_address) return false; if (aSorted[i].last_alive !== bSorted[i].last_alive) return false; } return true; }; useEffect(() => { let polling: ReturnType | null = null; const fetchClients = () => { if (inputActive) return; fetchClientsWithoutDescription().then(list => { setClients(prev => (isEqual(prev, list) ? prev : list)); }); }; fetchClients(); polling = setInterval(fetchClients, 5000); return () => { if (polling) clearInterval(polling); }; }, [inputActive]); const handleDescriptionChange = (uuid: string, value: string) => { setDescriptions(prev => ({ ...prev, [uuid]: value })); }; const handleSave = (uuid: string) => { setClientDescription(uuid, descriptions[uuid] || '') .then(() => { setClients(prev => prev.filter(c => c.uuid !== uuid)); }) .catch(err => { console.error('Fehler beim Speichern der Beschreibung:', err); }); }; if (loading) return
Lade neue Clients ...
; return (

Erweiterungsmodus: Neue Clients zuordnen

{ if (!props.last_alive) return ''; let iso = props.last_alive; if (!iso.endsWith('Z')) iso += 'Z'; const date = new Date(iso); const pad = (n: number) => n.toString().padStart(2, '0'); return `${pad(date.getDate())}.${pad(date.getMonth() + 1)}.${date.getFullYear()} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`; }} /> ( handleDescriptionChange(props.uuid, e.value as string)} focus={() => setInputActive(true)} blur={() => setInputActive(false)} /> )} /> (
handleSave(props.uuid)} /> { e.stopPropagation(); handleDelete(props.uuid); }} />
)} />
{clients.length === 0 &&
Keine neuen Clients ohne Beschreibung.
} {/* Syncfusion Dialog für Sicherheitsabfrage */} {showDialog && deleteClientId && ( { const client = clients.find(c => c.uuid === deleteClientId); const hostname = client?.hostname ? ` (${client.hostname})` : ''; return client ? `Möchten Sie diesen Client${hostname} wirklich entfernen?` : 'Client nicht gefunden.'; })()} showCloseIcon={true} width="400px" buttons={[ { click: confirmDelete, buttonModel: { content: 'Ja', isPrimary: true } }, { click: cancelDelete, buttonModel: { content: 'Abbrechen' } }, ]} close={cancelDelete} /> )}
); }; export default SetupMode;