diff --git a/src/pages/views/workspace/ToolActivityLog.tsx b/src/pages/views/workspace/ToolActivityLog.tsx index 1758c87..6986084 100644 --- a/src/pages/views/workspace/ToolActivityLog.tsx +++ b/src/pages/views/workspace/ToolActivityLog.tsx @@ -11,8 +11,6 @@ import React, { useState} from 'react'; import type { ToolActivity } from './useWorkspace'; import { useLanguage } from '../../../providers/language/LanguageContext'; -type TranslateFn = (key: string, params?: Record) => string; - interface ToolActivityLogProps { activities: ToolActivity[]; } @@ -52,79 +50,132 @@ function _formatArgs(args: Record, isError: boolean): string { return parts.join(', ') || (isError ? JSON.stringify(args) : ''); } -function _formatResult(result: string, translate: TranslateFn): string { - if (!result) return ''; - const trimmed = result.trim(); - - if (trimmed.startsWith('{') || trimmed.startsWith('[')) { - try { - const parsed = JSON.parse(trimmed); - if (Array.isArray(parsed)) { - return translate('{count} Ergebnisse', { count: parsed.length }); - } - if (typeof parsed === 'object' && parsed !== null) { - const keys = Object.keys(parsed); - if (parsed.count !== undefined) return translate('{count} Einträge', { count: parsed.count }); - if (parsed.total !== undefined) return translate('{count} Einträge', { count: parsed.total }); - if (parsed.rows && Array.isArray(parsed.rows)) { - return translate('{count} Zeilen', { count: parsed.rows.length }); - } - if (parsed.data && Array.isArray(parsed.data)) { - return translate('{count} Einträge', { count: parsed.data.length }); - } - if (parsed.result !== undefined) { - const r = String(parsed.result); - return r.length > 120 ? r.slice(0, 117) + '...' : r; - } - if (keys.length <= 3) { - return keys.map((k) => `${k}: ${String(parsed[k]).slice(0, 40)}`).join(', '); - } - return translate('Objekt ({count} Felder)', { count: keys.length }); - } - } catch { - // not valid JSON - } - } - - return trimmed.length > 150 ? trimmed.slice(0, 147) + '...' : trimmed; -} - -function _getToolLabel(toolName: string, translate: TranslateFn): string { - const labels: Record = { - browseTable: translate('Tabelle durchsuchen'), - queryTable: translate('Tabelle abfragen'), - aggregateTable: translate('Tabelle aggregieren'), - browseContainer: translate('Datei durchsuchen'), - readContentObjects: translate('Inhalte lesen'), - extractContainerItem: translate('Element extrahieren'), - queryFeatureInstance: translate('Feature abfragen'), - requestToolbox: translate('Toolbox anfordern'), - searchDocuments: translate('Dokumente suchen'), - getFileInfo: translate('Datei-Info abrufen'), - listFiles: translate('Dateien auflisten'), - listTables: translate('Tabellen auflisten'), - getTableSchema: translate('Tabellenschema abrufen'), - createRecord: translate('Datensatz erstellen'), - updateRecord: translate('Datensatz aktualisieren'), - deleteRecord: translate('Datensatz löschen'), - }; - return labels[toolName] || toolName; -} - -function _getStatusLabel(status: string, translate: TranslateFn): string { - switch (status) { - case 'calling': return translate('läuft'); - case 'success': return translate('OK'); - case 'error': return translate('Fehler'); - default: return status; - } -} - export const ToolActivityLog: React.FC = ({ activities }) => { const { t } = useLanguage(); const [expandedId, setExpandedId] = useState(null); - const translate: TranslateFn = t; + const _formatResult = (result: string): string => { + if (!result) return ''; + const trimmed = result.trim(); + + if (trimmed.startsWith('{') || trimmed.startsWith('[')) { + try { + const parsed = JSON.parse(trimmed); + if (Array.isArray(parsed)) { + return t('{count} Ergebnisse', { count: parsed.length }); + } + if (typeof parsed === 'object' && parsed !== null) { + const keys = Object.keys(parsed); + if (parsed.count !== undefined) return t('{count} Einträge', { count: parsed.count }); + if (parsed.total !== undefined) return t('{count} Einträge', { count: parsed.total }); + if (parsed.rows && Array.isArray(parsed.rows)) { + return t('{count} Zeilen', { count: parsed.rows.length }); + } + if (parsed.data && Array.isArray(parsed.data)) { + return t('{count} Einträge', { count: parsed.data.length }); + } + if (parsed.result !== undefined) { + const r = String(parsed.result); + return r.length > 120 ? r.slice(0, 117) + '...' : r; + } + if (keys.length <= 3) { + return keys.map((k) => `${k}: ${String(parsed[k]).slice(0, 40)}`).join(', '); + } + return t('Objekt ({count} Felder)', { count: keys.length }); + } + } catch { + // not valid JSON + } + } + + return trimmed.length > 150 ? trimmed.slice(0, 147) + '...' : trimmed; + }; + + const _getToolLabel = (toolName: string): string => { + switch (toolName) { + case 'addNode': return t('Knoten hinzufügen'); + case 'aggregateTable': return t('Tabelle aggregieren'); + case 'browseContainer': return t('Datei durchsuchen'); + case 'browseDataSource': return t('Datenquelle durchsuchen'); + case 'browseTable': return t('Tabelle durchsuchen'); + case 'clickup_createTask': return t('ClickUp-Aufgabe erstellen'); + case 'clickup_searchTasks': return t('ClickUp-Aufgaben suchen'); + case 'clickup_updateTask': return t('ClickUp-Aufgabe aktualisieren'); + case 'connectNodes': return t('Knoten verbinden'); + case 'copyFile': return t('Datei kopieren'); + case 'createChart': return t('Diagramm erstellen'); + case 'createFolder': return t('Ordner anlegen'); + case 'createRecord': return t('Datensatz erstellen'); + case 'deleteFile': return t('Datei löschen'); + case 'deleteFolder': return t('Ordner löschen'); + case 'deleteRecord': return t('Datensatz löschen'); + case 'describeImage': return t('Bild beschreiben'); + case 'detectLanguage': return t('Sprache erkennen'); + case 'downloadFromDataSource': return t('Aus Datenquelle laden'); + case 'executeCode': return t('Code ausführen'); + case 'extractContainerItem': return t('Element extrahieren'); + case 'generateImage': return t('Bild erzeugen'); + case 'getFileInfo': return t('Datei-Info abrufen'); + case 'getTableSchema': return t('Tabellenschema abrufen'); + case 'jira_connect': return t('Jira verbinden'); + case 'jira_exportTickets': return t('Jira-Tickets exportieren'); + case 'jira_importTickets': return t('Jira-Tickets importieren'); + case 'listAvailableNodeTypes': return t('Verfügbare Knotentypen auflisten'); + case 'listConnections': return t('Verbindungen auflisten'); + case 'listFiles': return t('Dateien auflisten'); + case 'listFolders': return t('Ordner auflisten'); + case 'listTables': return t('Tabellen auflisten'); + case 'listWorkflowHistory': return t('Workflow-Verlauf'); + case 'moveFile': return t('Datei verschieben'); + case 'moveFolder': return t('Ordner verschieben'); + case 'neutralizeData': return t('Daten neutralisieren'); + case 'outlook_composeAndDraftReply': return t('Outlook-Antwort entwerfen'); + case 'outlook_readEmails': return t('Outlook-E-Mails lesen'); + case 'outlook_searchEmails': return t('Outlook durchsuchen'); + case 'outlook_sendDraft': return t('Outlook-Entwurf senden'); + case 'queryFeatureInstance': return t('Feature abfragen'); + case 'queryTable': return t('Tabelle abfragen'); + case 'readContentObjects': return t('Inhalte lesen'); + case 'readFile': return t('Datei lesen'); + case 'readUrl': return t('URL lesen'); + case 'readWorkflowGraph': return t('Workflow-Graph lesen'); + case 'readWorkflowMessages': return t('Workflow-Nachrichten lesen'); + case 'removeNode': return t('Knoten entfernen'); + case 'renderDocument': return t('Dokument rendern'); + case 'replaceInFile': return t('Text in Datei ersetzen'); + case 'requestToolbox': return t('Toolbox anfordern'); + case 'renameFile': return t('Datei umbenennen'); + case 'renameFolder': return t('Ordner umbenennen'); + case 'searchDataSource': return t('In Datenquelle suchen'); + case 'searchDocuments': return t('Dokumente suchen'); + case 'searchInFileContent': return t('In Datei suchen'); + case 'sendMail': return t('E-Mail senden'); + case 'setNodeParameter': return t('Knotenparameter setzen'); + case 'sharepoint_findDocuments': return t('SharePoint-Dokumente finden'); + case 'sharepoint_readDocuments': return t('SharePoint-Dokumente lesen'); + case 'sharepoint_upload': return t('SharePoint-Upload'); + case 'speechToText': return t('Sprache zu Text'); + case 'summarizeContent': return t('Inhalt zusammenfassen'); + case 'tagFile': return t('Datei taggen'); + case 'textToSpeech': return t('Text zu Sprache'); + case 'translateText': return t('Text übersetzen'); + case 'trustee_refreshAccountingData': return t('Treuhand-Buchhaltung aktualisieren'); + case 'uploadToExternal': return t('Extern hochladen'); + case 'validateGraph': return t('Graph validieren'); + case 'webSearch': return t('Websuche'); + case 'writeFile': return t('Datei schreiben'); + default: return toolName; + } + }; + + const _getStatusLabel = (status: string): string => { + switch (status) { + case 'calling': return t('läuft'); + case 'success': return t('OK'); + case 'error': return t('Fehler'); + default: return status; + } + }; if (!activities.length) { return ( @@ -139,11 +190,11 @@ export const ToolActivityLog: React.FC = ({ activities }) {activities.map(activity => { const isError = activity.status === 'error'; const isExpanded = expandedId === activity.id; - const friendlyName = _getToolLabel(activity.toolName, translate); + const friendlyName = _getToolLabel(activity.toolName); const argsText = activity.args && Object.keys(activity.args).length > 0 ? _formatArgs(activity.args, isError) : ''; - const resultText = activity.result ? _formatResult(activity.result, translate) : ''; + const resultText = activity.result ? _formatResult(activity.result) : ''; return (
= ({ activities }) : 'var(--color-error, #f44336)', color: '#fff', }}> - {_getStatusLabel(activity.status, translate)} + {_getStatusLabel(activity.status)}