import DragIndicatorIcon from "@mui/icons-material/DragIndicator"; import { Box, CircularProgress, Tooltip, Typography } from "@mui/material"; import { useNavigate } from "@tanstack/react-router"; import { useEffect, useState } from "react"; import type { Kennzahl } from "../types/kpi"; import { getDisplayType } from "../types/kpi"; import { fetchKennzahlen as fetchK } from "../util/api"; import { API_HOST } from "../util/api"; type ConfigTableProps = { from?: string; }; export function ConfigTable({ from }: ConfigTableProps) { const navigate = useNavigate(); const [kennzahlen, setKennzahlen] = useState([]); const [draggedItem, setDraggedItem] = useState(null); const [isUpdatingPositions, setIsUpdatingPositions] = useState(false); const [loading, setLoading] = useState(true); useEffect(() => { const fetchKennzahlen = async () => { while (true) { try { console.log("Fetching kennzahlen from API..."); const data = await fetchK(); console.log("Fetched kennzahlen:", data); const sortedData = data.sort( (a: Kennzahl, b: Kennzahl) => a.position - b.position, ); setKennzahlen(sortedData); setLoading(false); break; } catch (err) { console.error("Error fetching kennzahlen:", err); await new Promise((resolve) => setTimeout(resolve, 2000)); } } }; fetchKennzahlen(); }, []); const handleToggleActive = async (id: number) => { const kennzahl = kennzahlen.find((k) => k.id === id); if (!kennzahl) return; try { const response = await fetch( `${API_HOST}/api/kpi_setting/${id}`, { method: "PUT", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ active: !kennzahl.active, }), }, ); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const updatedKennzahl = await response.json(); setKennzahlen((prev) => prev.map((item) => (item.id === id ? updatedKennzahl : item)), ); } catch (err) { console.error("Error toggling active status:", err); setKennzahlen((prev) => prev.map((item) => (item.id === id ? kennzahl : item)), ); } }; const updatePositionsInBackend = async (reorderedKennzahlen: Kennzahl[]) => { setIsUpdatingPositions(true); try { const positionUpdates = reorderedKennzahlen.map((kennzahl, index) => ({ id: kennzahl.id, position: index + 1, })); const response = await fetch( `${API_HOST}/api/kpi_setting/update-kpi-positions`, { method: "PUT", headers: { "Content-Type": "application/json", }, body: JSON.stringify(positionUpdates), }, ); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const updatedKennzahlen = await response.json(); setKennzahlen(updatedKennzahlen); } catch (err) { console.error("Error updating positions:", err); window.location.reload(); } finally { setIsUpdatingPositions(false); } }; const handleDragStart = ( e: React.DragEvent, item: Kennzahl, ) => { setDraggedItem(item); e.dataTransfer.effectAllowed = "move"; }; const handleDragOver = (e: React.DragEvent) => { e.preventDefault(); e.dataTransfer.dropEffect = "move"; }; const handleDrop = async ( e: React.DragEvent, targetItem: Kennzahl, ) => { e.preventDefault(); if (!draggedItem || draggedItem.id === targetItem.id) return; const draggedIndex = kennzahlen.findIndex( (item) => item.id === draggedItem.id, ); const targetIndex = kennzahlen.findIndex( (item) => item.id === targetItem.id, ); const newKennzahlen = [...kennzahlen]; const [removed] = newKennzahlen.splice(draggedIndex, 1); newKennzahlen.splice(targetIndex, 0, removed); setKennzahlen(newKennzahlen); setDraggedItem(null); await updatePositionsInBackend(newKennzahlen); }; const handleDragEnd = () => { setDraggedItem(null); }; const handleRowClick = (kennzahl: Kennzahl, e: React.MouseEvent) => { if (draggedItem || isUpdatingPositions) { return; } const target = e.target as HTMLElement; if ( target.tagName === "INPUT" && (target as HTMLInputElement).type === "checkbox" ) { return; } if (target.closest(".drag-handle")) { return; } navigate({ to: `/config-detail/$kpiId`, params: { kpiId: kennzahl.id.toString() }, search: from ? { from } : undefined, }); }; if (loading) { return ( Lade Kennzahlen-Konfiguration... ); } return ( {kennzahlen.map((kennzahl) => ( handleDragStart(e, kennzahl)} onDragOver={handleDragOver} onDrop={(e) => handleDrop(e, kennzahl)} onDragEnd={handleDragEnd} onClick={(e) => handleRowClick(kennzahl, e)} style={{ borderBottom: "1px solid #e0e0e0", cursor: isUpdatingPositions ? "default" : "pointer", backgroundColor: draggedItem?.id === kennzahl.id ? "#f0f0f0" : "white", opacity: draggedItem?.id === kennzahl.id ? 0.5 : 1, }} onMouseEnter={(e) => { if (!draggedItem && !isUpdatingPositions) { e.currentTarget.style.backgroundColor = "#f9f9f9"; } }} onMouseLeave={(e) => { if (!draggedItem && !isUpdatingPositions) { e.currentTarget.style.backgroundColor = "white"; } }} > ))}
Aktiv Name Format
Neuanordnung der Kennzahlen
Hier können Sie die Kennzahlen nach Belieben per Drag and Drop neu anordnen. } placement="left" arrow >
handleToggleActive(kennzahl.id)} disabled={isUpdatingPositions} style={{ width: "18px", height: "18px", cursor: isUpdatingPositions ? "default" : "pointer", accentColor: "#383838", }} onClick={(e) => e.stopPropagation()} /> {kennzahl.name} {getDisplayType(kennzahl.type)}
); }