/** * PromptsPage * * Page for managing prompt templates using FormGeneratorTable. * Follows the pattern established in AdminUsersPage/WorkflowsPage. */ import React, { useState, useMemo, useEffect } from 'react'; import { usePrompts, usePromptOperations } from '../../hooks/usePrompts'; import { FormGeneratorTable } from '../../components/FormGenerator/FormGeneratorTable'; import { FormGeneratorForm } from '../../components/FormGenerator/FormGeneratorForm'; import { FaSync, FaPlus } from 'react-icons/fa'; import styles from '../admin/Admin.module.css'; interface Prompt { id: string; name: string; content: string; [key: string]: any; } export const PromptsPage: React.FC = () => { // Data hook const { prompts, attributes, permissions, pagination, loading, error, refetch, fetchPromptById, updateOptimistically, } = usePrompts(); // Operations hook const { handlePromptCreate, handlePromptUpdate, handlePromptDelete, handleInlineUpdate, deletingPrompts, } = usePromptOperations(); const [showCreateModal, setShowCreateModal] = useState(false); const [editingPrompt, setEditingPrompt] = useState(null); // Initial fetch useEffect(() => { refetch(); }, []); // Generate columns from attributes - exclude ID fields from display const columns = useMemo(() => { // Fields to hide in table view const hiddenColumns = ['id', 'mandateId', '_createdAt', '_modifiedAt', '_hideDelete', '_permissions']; const cols = (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.name === 'content' ? 300 : attr.width || 150, minWidth: attr.minWidth || 100, maxWidth: attr.name === 'content' ? 500 : attr.maxWidth || 400, fkSource: (attr as any).fkSource, fkDisplayField: (attr as any).fkDisplayField, })); // Add _createdBy column with FK resolution to show username cols.push({ key: '_createdBy', label: 'Created By', type: 'text' as any, sortable: true, filterable: false, searchable: false, width: 150, minWidth: 100, maxWidth: 250, fkSource: '/api/users/', fkDisplayField: 'username', }); return cols; }, [attributes]); // Check permissions const canCreate = permissions?.create !== 'n'; const canUpdate = permissions?.update !== 'n'; const canDelete = permissions?.delete !== 'n'; // Handle edit click const handleEditClick = async (prompt: Prompt) => { const fullPrompt = await fetchPromptById(prompt.id); if (fullPrompt) { setEditingPrompt(fullPrompt as Prompt); } }; // Handle create submit const handleCreateSubmit = async (data: Partial) => { const result = await handlePromptCreate({ name: data.name || '', content: data.content || '' }); if (result?.success) { setShowCreateModal(false); refetch(); } }; // Handle edit submit const handleEditSubmit = async (data: Partial) => { if (!editingPrompt) return; const result = await handlePromptUpdate(editingPrompt.id, { name: data.name || editingPrompt.name, content: data.content || editingPrompt.content }); if (result.success) { setEditingPrompt(null); refetch(); } }; // Handle duplicate prompt const handleDuplicate = async (prompt: Prompt) => { const result = await handlePromptCreate({ name: `Kopie von ${prompt.name || 'Prompt'}`, content: prompt.content || '' }); if (result?.success) { refetch(); } }; // Handle delete single prompt (confirmation handled by DeleteActionButton) const handleDelete = async (prompt: Prompt) => { const success = await handlePromptDelete(prompt.id); if (success) { refetch(); } }; // Form attributes for create/edit modal const formAttributes = useMemo(() => { const excludedFields = ['id', 'mandateId', 'isSystem', '_createdBy', '_createdAt', '_modifiedAt', '_hideDelete', '_permissions']; return (attributes || []) .filter(attr => !excludedFields.includes(attr.name)); }, [attributes]); if (error) { return (
⚠️

Fehler beim Laden der Prompts: {error}

); } return (

Prompts

Prompt-Templates verwalten

{canCreate && ( )}
deletingPrompts.has(row.id), }] : []), ]} onDelete={handleDelete} hookData={{ refetch, permissions, pagination, handleDelete: handlePromptDelete, handleInlineUpdate, updateOptimistically, }} emptyMessage="Keine Prompts gefunden" />
{/* Create Modal */} {showCreateModal && (
setShowCreateModal(false)}>
e.stopPropagation()}>

Neuer Prompt

{formAttributes.length === 0 ? (
Lade Formular...
) : ( setShowCreateModal(false)} submitButtonText="Erstellen" cancelButtonText="Abbrechen" /> )}
)} {/* Edit Modal */} {editingPrompt && (
setEditingPrompt(null)}>
e.stopPropagation()}>

Prompt bearbeiten

{formAttributes.length === 0 ? (
Lade Formular...
) : ( setEditingPrompt(null)} submitButtonText="Speichern" cancelButtonText="Abbrechen" /> )}
)}
); }; export default PromptsPage;