/** * TrusteePositionsView * * Positions-Verwaltung für eine Trustee-Instanz. * Verwendet FormGeneratorTable für konsistentes UI. */ import React, { useState, useMemo, useEffect } from 'react'; import { useTrusteePositions, useTrusteePositionOperations, TrusteePosition } from '../../../hooks/useTrustee'; import { useInstanceId } from '../../../hooks/useCurrentInstance'; import { FormGeneratorTable } from '../../../components/FormGenerator/FormGeneratorTable'; import { FormGeneratorForm } from '../../../components/FormGenerator/FormGeneratorForm'; import { FaSync, FaReceipt } from 'react-icons/fa'; import styles from '../../admin/Admin.module.css'; export const TrusteePositionsView: React.FC = () => { const instanceId = useInstanceId(); // Entity hook const { items: positions, attributes, permissions, pagination, loading, error, refetch, fetchById, updateOptimistically, removeOptimistically, } = useTrusteePositions(); // Operations hook const { handleDelete, handleCreate, handleUpdate, deletingItems, } = useTrusteePositionOperations(); // Modal state const [editingPosition, setEditingPosition] = useState(null); const [isCreateMode, setIsCreateMode] = useState(false); // Initial fetch useEffect(() => { if (instanceId) { refetch(); } }, [instanceId]); // Hidden columns (not shown in table view, but available in form) const hiddenColumns = ['desc', 'featureInstanceId', 'mandateId']; // Generate columns from attributes + add system columns const columns = useMemo(() => { const attrColumns = (attributes || []) .filter(attr => !hiddenColumns.includes(attr.name)) .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, })); // Add _createdAt system column attrColumns.push({ key: '_createdAt', label: 'Erstellt am', type: 'timestamp' as any, sortable: true, filterable: false, searchable: false, width: 150, minWidth: 120, maxWidth: 200, }); return attrColumns; }, [attributes]); // Check permissions const canCreate = permissions?.create !== 'n'; const canUpdate = permissions?.update !== 'n'; const canDelete = permissions?.delete !== 'n'; // Handle edit click const handleEditClick = async (pos: TrusteePosition) => { const fullPos = await fetchById(pos.id); if (fullPos) { setEditingPosition(fullPos); setIsCreateMode(false); } }; // Handle create click const handleCreateClick = () => { setEditingPosition(null); setIsCreateMode(true); }; // Handle form submit const handleFormSubmit = async (data: Partial) => { // Auto-calculate VAT if provided const processedData = { ...data }; if (processedData.bookingAmount && processedData.vatPercentage && !processedData.vatAmount) { processedData.vatAmount = processedData.bookingAmount * (processedData.vatPercentage / 100); } if (isCreateMode) { const result = await handleCreate(processedData); if (result.success) { setIsCreateMode(false); refetch(); } } else if (editingPosition) { const result = await handleUpdate(editingPosition.id, processedData); if (result.success) { setEditingPosition(null); refetch(); } } }; // Handle delete (confirmation handled by DeleteActionButton) const handleDeletePos = async (pos: TrusteePosition) => { removeOptimistically(pos.id); const success = await handleDelete(pos.id); if (!success) { refetch(); // Revert on error } }; // Close modal const handleCloseModal = () => { setEditingPosition(null); setIsCreateMode(false); }; // Form attributes (exclude system fields) const formAttributes = useMemo(() => { const excludedFields = ['id', 'mandateId', 'instanceId', '_createdBy', '_createdAt', '_modifiedAt', '_modifiedBy']; return (attributes || []).filter(attr => !excludedFields.includes(attr.name)); }, [attributes]); // Handle inline update const handleInlineUpdate = async (itemId: string, updateData: Partial, row: TrusteePosition) => { updateOptimistically(itemId, updateData); const result = await handleUpdate(itemId, { ...row, ...updateData }); if (!result.success) { refetch(); // Revert on error } }; if (error) { return (
⚠️

Fehler beim Laden der Positionen: {error}

); } return (

Buchungspositionen verwalten

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

Keine Positionen vorhanden

Erstellen Sie eine neue Position, um zu beginnen.

{canCreate && ( )}
) : ( deletingItems.has(row.id), }] : []), ]} onDelete={handleDeletePos} hookData={{ refetch, permissions, pagination, handleDelete, handleInlineUpdate, updateOptimistically, }} emptyMessage="Keine Positionen gefunden" /> )}
{/* Create/Edit Modal */} {(editingPosition || isCreateMode) && (
e.stopPropagation()}>

{isCreateMode ? 'Neue Position' : 'Position bearbeiten'}

{formAttributes.length === 0 ? (
Lade Formular...
) : ( )}
)}
); }; export default TrusteePositionsView;