diff --git a/src/App.tsx b/src/App.tsx index 6655203..1b6228f 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -11,7 +11,7 @@ import { AuthProvider } from './auth/authProvider'; import { ProtectedRoute } from './auth/ProtectedRoute'; import Home from './pages/Home'; import Dateien from './pages/Dateien/Dateien'; -import TeamBereich from './pages/Mitglieder/TeamBereich'; +import TeamBereich from './pages/TeamBereich/TeamBereich'; import Dashboard from './pages/Dashboard'; import Einstellungen from './pages/Einstellungen/Einstellungen'; // Import the global light theme CSS variables as default diff --git a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashbaordChatAreaStatusDisplay.tsx b/src/components/Dashboard/DashboardChat/DashboardChatArea/DashbaordChatAreaStatusDisplay.tsx index 55e1000..5edb5a4 100644 --- a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashbaordChatAreaStatusDisplay.tsx +++ b/src/components/Dashboard/DashboardChat/DashboardChatArea/DashbaordChatAreaStatusDisplay.tsx @@ -7,11 +7,34 @@ const WorkflowStatusDisplay: React.FC = ({ currentWorkflowId, workflowStatus, workflowCompleted, - onStartNewWorkflow + onStartNewWorkflow, + handleRetry, + shouldShowRetryButton }) => { return ( - {currentWorkflowId && !workflowCompleted && ( + {currentWorkflowId && shouldShowRetryButton() && ( + +
+ + Workflow failed. + + +
+
+ )} + {currentWorkflowId && !workflowCompleted && !shouldShowRetryButton() && ( = ({ handleFileAttach, handleFileRemove, handleFilesSelect, + handleRetry, // Workflow state isWorkflowRunning, - isStoppingWorkflow + isStoppingWorkflow, + shouldShowRetryButton } = useChatLogic({ selectedPrompt, onPromptUsed, @@ -73,6 +75,8 @@ const DashboardChatArea: React.FC = ({ messagesLoading={messagesLoading} onStartNewWorkflow={startNewWorkflow} messagesEndRef={messagesEndRef} + handleRetry={handleRetry} + shouldShowRetryButton={shouldShowRetryButton} /> = ({ messagesError, messagesLoading, onStartNewWorkflow, - messagesEndRef + messagesEndRef, + handleRetry, + shouldShowRetryButton }) => { return ( = ({ workflowStatus={workflowStatus} workflowCompleted={workflowCompleted} onStartNewWorkflow={onStartNewWorkflow} + handleRetry={handleRetry} + shouldShowRetryButton={shouldShowRetryButton} />
diff --git a/src/components/Dashboard/DashboardChat/DashboardChatArea/dashboardChatAreaLogic.ts b/src/components/Dashboard/DashboardChat/DashboardChatArea/dashboardChatAreaLogic.ts index eb699f5..f567300 100644 --- a/src/components/Dashboard/DashboardChat/DashboardChatArea/dashboardChatAreaLogic.ts +++ b/src/components/Dashboard/DashboardChat/DashboardChatArea/dashboardChatAreaLogic.ts @@ -229,6 +229,55 @@ export const useChatLogic = ({ const isStoppingWorkflow = currentWorkflowId ? stoppingWorkflows.has(currentWorkflowId) : false; + const handleRetry = async () => { + if (!currentWorkflowId || !messages.length) { + console.error('No workflow ID or messages available for retry'); + return; + } + + // Find the last user message to retry + const userMessages = messages.filter(msg => msg.role === 'user'); + const lastUserMessage = userMessages[userMessages.length - 1]; + + if (!lastUserMessage) { + console.error('No user message found to retry'); + return; + } + + console.log('Retrying workflow with last user message:', lastUserMessage.content); + + try { + // Extract file IDs if available from the message + const fileIds = lastUserMessage.fileIds || []; + + // Start the workflow again with the same prompt and files + const result = await startWorkflow({ + prompt: lastUserMessage.content, + listFileId: fileIds + }, currentWorkflowId); + + if (result.success) { + console.log('Workflow retry started successfully'); + // Reset workflow completion state to resume polling + setWorkflowCompleted(false); + } else { + console.error('Failed to retry workflow:', result.error); + } + } catch (error) { + console.error('Error retrying workflow:', error); + } + }; + + const shouldShowRetryButton = () => { + if (!workflowStatus) return false; + + const statusLower = workflowStatus.status.toLowerCase(); + return statusLower === 'error' || + statusLower === 'failed' || + statusLower === 'stopped' || + statusLower === 'cancelled'; + }; + return { // State inputValue, @@ -257,9 +306,11 @@ export const useChatLogic = ({ handleFileAttach, handleFileRemove, handleFilesSelect, + handleRetry, // Workflow state isWorkflowRunning, - isStoppingWorkflow + isStoppingWorkflow, + shouldShowRetryButton }; }; \ No newline at end of file diff --git a/src/components/Dashboard/DashboardChat/DashboardChatArea/dashboardChatAreaTypes.ts b/src/components/Dashboard/DashboardChat/DashboardChatArea/dashboardChatAreaTypes.ts index e92faf9..9f163da 100644 --- a/src/components/Dashboard/DashboardChat/DashboardChatArea/dashboardChatAreaTypes.ts +++ b/src/components/Dashboard/DashboardChat/DashboardChatArea/dashboardChatAreaTypes.ts @@ -62,6 +62,8 @@ export interface MessageListProps { messagesLoading: boolean; onStartNewWorkflow: () => void; messagesEndRef: React.RefObject; + handleRetry: () => Promise; + shouldShowRetryButton: () => boolean; } export interface WorkflowStatusDisplayProps { @@ -69,4 +71,6 @@ export interface WorkflowStatusDisplayProps { workflowStatus: WorkflowStatus | null; workflowCompleted: boolean; onStartNewWorkflow: () => void; + handleRetry: () => Promise; + shouldShowRetryButton: () => boolean; } \ No newline at end of file diff --git a/src/components/Dashboard/DashboardChat/DashboardChatHistory/DashboardChatHistoryItem.tsx b/src/components/Dashboard/DashboardChat/DashboardChatHistory/DashboardChatHistoryItem.tsx index a13d917..d3d1745 100644 --- a/src/components/Dashboard/DashboardChat/DashboardChatHistory/DashboardChatHistoryItem.tsx +++ b/src/components/Dashboard/DashboardChat/DashboardChatHistory/DashboardChatHistoryItem.tsx @@ -1,6 +1,7 @@ import React, { useState, useEffect } from 'react'; import { FaArrowRight } from 'react-icons/fa'; import { AiOutlineDelete } from 'react-icons/ai'; +import { motion } from 'framer-motion'; import { useWorkflowOperations, useWorkflowMessages, Workflow } from '../../../../hooks/useWorkflows'; import styles from './DashboardChatHistoryItem.module.css'; @@ -50,16 +51,8 @@ function DashboardChatHistoryItem({ workflow, onDelete, onResume }: DashboardCha const getStatusColor = (status: string) => { switch (status.toLowerCase()) { - case 'completed': - case 'finished': - case 'done': - return 'var(--color-secondary)'; - case 'running': - case 'processing': - return 'var(--color-gray)'; case 'error': case 'failed': - return 'var(--color-red)'; case 'stopped': case 'cancelled': return 'var(--color-red)'; @@ -70,13 +63,6 @@ function DashboardChatHistoryItem({ workflow, onDelete, onResume }: DashboardCha const getStatusBackgroundColor = (status: string) => { switch (status.toLowerCase()) { - case 'completed': - case 'finished': - case 'done': - return 'var(--color-secondary-disabled)'; - case 'running': - case 'processing': - return 'var(--color-gray-disabled)'; case 'error': case 'failed': case 'stopped': @@ -87,6 +73,59 @@ function DashboardChatHistoryItem({ workflow, onDelete, onResume }: DashboardCha } }; + const shouldShowStatus = (status: string) => { + const statusLower = status.toLowerCase(); + return statusLower === 'error' || + statusLower === 'failed' || + statusLower === 'stopped' || + statusLower === 'cancelled'; + }; + + const isRunning = (status: string) => { + const statusLower = status.toLowerCase(); + return statusLower === 'running' || statusLower === 'processing'; + }; + + const renderStatusIndicator = () => { + if (isRunning(workflow.status)) { + return ( + + ); + } + + if (shouldShowStatus(workflow.status)) { + return ( + + {workflow.status.toUpperCase()} + + ); + } + + return null; + }; + const truncateMessage = (message: string, maxLength: number = 150) => { if (message.length <= maxLength) return message; return message.substring(0, maxLength) + '...'; @@ -101,15 +140,7 @@ function DashboardChatHistoryItem({ workflow, onDelete, onResume }: DashboardCha Workflow {workflow.id.substring(0, 8)}...
- - {workflow.status.toUpperCase()} - + {renderStatusIndicator()} {workflow.currentRound && ( Round {workflow.currentRound} diff --git a/src/pages/Dateien/Dateien.module.css b/src/pages/Dateien/Dateien.module.css index 4e798eb..f74d101 100644 --- a/src/pages/Dateien/Dateien.module.css +++ b/src/pages/Dateien/Dateien.module.css @@ -5,7 +5,6 @@ flex-direction: column; align-self: stretch; border-radius: 30px; - border: 1px solid var(--color-gray-disabled); background: var(--color-bg); position: relative; box-shadow: 0px 2px 6px 0px rgba(194, 194, 194, 0.10); diff --git a/src/pages/Mitglieder/TeamBereich.tsx b/src/pages/Mitglieder/TeamBereich.tsx deleted file mode 100644 index 24ab682..0000000 --- a/src/pages/Mitglieder/TeamBereich.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import styles from './TeamBereich.module.css' - -import MitgliederItem from '../../components/Mitglieder/MitgliederItem'; -import { IoPersonAddSharp } from "react-icons/io5"; -import { useOrgUsers } from '../../hooks/useUsers'; - -function TeamBereich () { - - return ( -

Team-Bereich

- ); -} - -export default TeamBereich; - diff --git a/src/pages/Mitglieder/TeamBereich.module.css b/src/pages/TeamBereich/TeamBereich.module.css similarity index 98% rename from src/pages/Mitglieder/TeamBereich.module.css rename to src/pages/TeamBereich/TeamBereich.module.css index 848edca..24e02f6 100644 --- a/src/pages/Mitglieder/TeamBereich.module.css +++ b/src/pages/TeamBereich/TeamBereich.module.css @@ -66,7 +66,7 @@ .membersList { list-style: none; padding: 0; - margin: 0; + margin-top: 30px; width: 100%; overflow-y: auto; /* Enable vertical scrolling */ /* Space for the header line */ diff --git a/src/pages/TeamBereich/TeamBereich.tsx b/src/pages/TeamBereich/TeamBereich.tsx new file mode 100644 index 0000000..19294a9 --- /dev/null +++ b/src/pages/TeamBereich/TeamBereich.tsx @@ -0,0 +1,60 @@ +import styles from './TeamBereich.module.css' + +import MitgliederItem from '../../components/Mitglieder/MitgliederItem'; +import { IoPersonAddSharp } from "react-icons/io5"; +import { useOrgUsers } from '../../hooks/useUsers'; + +function TeamBereich () { + const { users, loading, error, refetch } = useOrgUsers(); + + if (loading) { + return ( +
+
+

Team-Bereich

+
+

Lade Mitglieder...

+
+ ); + } + + if (error) { + return ( +
+
+

Team-Bereich

+
+

Fehler beim Laden der Mitglieder: {error}

+
+ ); + } + + return ( +
+
+

Team-Bereich

+ +
+
+
    + {users.map((user) => ( + + ))} +
+ {users.length === 0 && ( +

Keine Mitglieder gefunden.

+ )} +
+ ); +} + +export default TeamBereich; +