import React, { useState } from 'react'; import ReactMarkdown from 'react-markdown'; import remarkGfm from 'remark-gfm'; import { FaExclamationTriangle } from 'react-icons/fa'; import { IoIosTrash, IoIosCheckmark, IoIosClose } from 'react-icons/io'; import { Message } from '../MessagesTypes'; import { formatTimestamp } from '../MessageUtils'; import { DocumentItem, ActionInfo } from '../MessageParts'; import { WorkflowFile } from '../../../../hooks/usePlayground'; import styles from '../Messages.module.css'; import { useLanguage } from '../../../../providers/language/LanguageContext'; export interface ChatMessageProps { message: Message; showDocuments?: boolean; renderDocument?: (document: any, message: Message) => React.ReactNode; onFileDelete?: (file: WorkflowFile) => Promise; onFileRemove?: (file: WorkflowFile) => Promise; onFileView?: (file: WorkflowFile) => Promise; onFileDownload?: (file: WorkflowFile) => Promise; deletingFiles?: Set; previewingFiles?: Set; removingFiles?: Set; downloadingFiles?: Set; workflowId?: string; onMessageDelete?: (messageId: string) => Promise; deletingMessages?: Set; } /** * Renders a single message in chat style (bubble UI) */ export const ChatMessage: React.FC = ({ message, showDocuments = true, renderDocument, onFileDelete, onFileRemove, onFileView, onFileDownload, deletingFiles, previewingFiles, removingFiles, downloadingFiles, workflowId, onMessageDelete, deletingMessages }) => { const { t } = useLanguage(); const isUser = message.role?.toLowerCase() === 'user'; const isError = message.actionProgress === 'fail' || message.actionProgress === 'error'; const messageClass = isUser ? styles.messageUser : styles.messageAssistant; const errorClass = isError ? styles.messageError : ''; const isDeleting = deletingMessages?.has(message.id) || false; // Message delete 2-click confirmation state const [isConfirmingDelete, setIsConfirmingDelete] = useState(false); const handleDeleteClick = (e: React.MouseEvent) => { e.stopPropagation(); setIsConfirmingDelete(true); }; const handleConfirmDelete = async (e: React.MouseEvent) => { e.stopPropagation(); setIsConfirmingDelete(false); if (onMessageDelete && message.id) { await onMessageDelete(message.id); } }; const handleCancelDelete = (e: React.MouseEvent) => { e.stopPropagation(); setIsConfirmingDelete(false); }; return (
{/* Error indicator for failed actions */} {isError && (
{t('Aktion fehlgeschlagen')}
)} {/* Message content */} {message.message && (

, h2: ({node, ...props}) =>

, h3: ({node, ...props}) =>

, h4: ({node, ...props}) =>

, h5: ({node, ...props}) =>

, h6: ({node, ...props}) =>
, p: ({node, ...props}) =>

, ul: ({node, ...props}) =>