diff --git a/ui/client-app/src/components/ChatWindow.js b/ui/client-app/src/components/ChatWindow.js index c2f2401..77dc975 100644 --- a/ui/client-app/src/components/ChatWindow.js +++ b/ui/client-app/src/components/ChatWindow.js @@ -1,14 +1,10 @@ import React, { useEffect, useRef, useState } from "react"; import ReactMarkdown from 'react-markdown'; import './ChatWindow.css'; -import FileListComponent from "./FileList"; -import DiffViewer from "./DiffViewer"; -import CodeChangePlan from "./CodeChangePlan"; import { FaRegCopy, FaCopy, FaVolumeUp, FaPlay, FaPause, FaDownload, FaSyncAlt } from 'react-icons/fa'; // Import the icons // Individual message component const ChatMessage = ({ message, index, onSynthesize, featureName = "default", activePlayingId, onPlayStateChange }) => { - const [selectedFile, setSelectedFile] = useState(null); const [isReasoningExpanded, setIsReasoningExpanded] = useState(false); const [audioUrl, setAudioUrl] = useState(null); const [isPlaying, setIsPlaying] = useState(false); @@ -81,13 +77,6 @@ setIsReasoningExpanded(!isReasoningExpanded); }; - const handleCloseDiff = () => { - setSelectedFile(null); - }; - - const handleFileClick = (file) => { - setSelectedFile(file); - }; // Function to copy text to clipboard const handleCopy = async () => { if (message.text) { @@ -210,13 +199,6 @@ )} - {message.code_changes && ( - - )} - {message.steps && ( - - )} - {selectedFile && } ); }; diff --git a/ui/client-app/src/components/CodeChangePlan.css b/ui/client-app/src/components/CodeChangePlan.css deleted file mode 100644 index b8fccea..0000000 --- a/ui/client-app/src/components/CodeChangePlan.css +++ /dev/null @@ -1,105 +0,0 @@ -/* Container for the list */ -.code-change-plan { - list-style: none; - padding: 0; - margin: 1rem 0; - font-family: 'Inter', sans-serif; - counter-reset: step-counter; -} - -/* Style for each list item */ -.code-change-plan-step { - background-color: #f7f9fc; - border: 1px solid #e0e6ed; - border-radius: 8px; - padding: 1rem; - margin-bottom: 0.75rem; - display: flex; - align-items: flex-start; - gap: 1rem; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); - transition: transform 0.2s ease, box-shadow 0.2s ease; - cursor: pointer; - position: relative; /* Required for absolute tooltip */ - counter-increment: step-counter; -} - -/* Add a hover effect */ -.code-change-plan-step:hover { - background-color: #e6e9ef; - transform: translateY(-2px); - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); -} - -/* Step prefix before each item */ -.code-change-plan-step::before { - content: "Step " counter(step-counter) "."; - font-size: 0.9rem; - font-weight: bold; - color: #3b82f6; - flex-shrink: 0; - margin-right: 0.5rem; -} - -/* Text content */ -.code-change-plan-step p { - margin: 0; - font-size: 0.9rem; - line-height: 1.5; - color: #333; - flex: 1; -} - -/* --- Updated Tooltip Styles --- */ -.step-details-popdown { - position: absolute; - left: 100%; - top: 0; - margin-left: 10px; - padding: 10px; - background-color: #ffffff; /* Lighter background, perhaps white or a very light grey */ - color: #333; /* Darker text for contrast on light background */ - border: 1px solid #e0e6ed; /* Border matching list items */ - border-radius: 8px; /* Matching border radius */ - white-space: nowrap; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); /* Softer, slightly larger shadow */ - z-index: 10; - display: flex; - flex-direction: column; - gap: 5px; -} - -.tooltip-action { - display: flex; - align-items: center; - gap: 8px; - font-weight: bold; - color: #333; /* Ensure action text is dark for readability */ -} - -.tooltip-file-path { - font-family: monospace; - font-size: 0.9em; - color: #555; /* Slightly darker grey for filepath */ - border-top: 1px solid #e0e6ed; /* Lighter border for separation */ - padding-top: 5px; - margin-top: 5px; -} - -/* Icon colors remain the same for clear visual cues */ -.create-icon { - color: #28a745; /* Green for create */ -} - -.delete-icon { - color: #dc3545; /* Red for delete */ -} - -.modify-icon { - color: #ffc107; /* Yellow for modify */ -} - -.code-change-plan { - overflow: visible; - position: relative; /* ensures tooltip is positioned correctly */ -} diff --git a/ui/client-app/src/components/CodeChangePlan.js b/ui/client-app/src/components/CodeChangePlan.js deleted file mode 100644 index 379a26b..0000000 --- a/ui/client-app/src/components/CodeChangePlan.js +++ /dev/null @@ -1,89 +0,0 @@ -import { createPortal } from 'react-dom'; -import { useRef, useState } from 'react'; -import ReactMarkdown from 'react-markdown'; -import './CodeChangePlan.css'; -import { FaPlus, FaTrash, FaEdit } from 'react-icons/fa'; - -// Tooltip component -const StepDetails = ({ stepItem, position }) => { - const style = { - position: 'absolute', - top: position?.top ?? 0, - left: position?.left ?? 0, - }; - - return ( -
-
- {stepItem.action === 'create' && } - {stepItem.action === 'delete' && } - {stepItem.action === 'modify' && } - - {stepItem.action === 'create' - ? 'Create File' - : stepItem.action === 'delete' - ? 'Delete File' - : stepItem.action === 'modify' - ? 'Modify File' - : stepItem.action} - -
-
{stepItem.file_path}
-
- ); -}; - -// Main component -const CodeChangePlan = ({ steps }) => { - const [hoveredStepIndex, setHoveredStepIndex] = useState(null); - const [tooltipPosition, setTooltipPosition] = useState(null); - const stepRefs = useRef([]); - - const handleMouseEnter = (index) => { - const stepElement = stepRefs.current[index]; - if (stepElement) { - const rect = stepElement.getBoundingClientRect(); - // const tooltipPadding = 10; - - setTooltipPosition({ - top: rect.bottom + window.scrollY + 6, // 6px spacing - left: rect.left + window.scrollX, - }); - } - setHoveredStepIndex(index); - }; - - const handleMouseLeave = () => { - setHoveredStepIndex(null); - setTooltipPosition(null); - }; - - return ( - <> -
    - {steps.map((step, index) => ( -
  • handleMouseEnter(index)} - onMouseLeave={handleMouseLeave} - ref={(el) => (stepRefs.current[index] = el)} - > - {step.change_instruction} -
  • - ))} -
- - {hoveredStepIndex !== null && - createPortal( - , - document.body - )} - - ); -}; - -export default CodeChangePlan; diff --git a/ui/client-app/src/components/DiffViewer.css b/ui/client-app/src/components/DiffViewer.css deleted file mode 100644 index eac3042..0000000 --- a/ui/client-app/src/components/DiffViewer.css +++ /dev/null @@ -1,12 +0,0 @@ -.d2h-code-side-linenumber, -.d2h-code-linenumber, -.d2h-info, -.d2h-file-header { - position: static !important; - background: inherit !important; - z-index: auto !important; -} - -ol li::before { - content: ""; -} \ No newline at end of file diff --git a/ui/client-app/src/components/DiffViewer.js b/ui/client-app/src/components/DiffViewer.js deleted file mode 100644 index ba5d04c..0000000 --- a/ui/client-app/src/components/DiffViewer.js +++ /dev/null @@ -1,133 +0,0 @@ -import React, { useState, useEffect } from "react"; -import { createTwoFilesPatch } from 'diff'; -import { parse, html } from 'diff2html'; -import 'diff2html/bundles/css/diff2html.min.css'; -import './DiffViewer.css'; - -const DiffViewer = ({ oldContent, newContent, filePath, onClose }) => { - const [diffHtml, setDiffHtml] = useState(""); - const [isDropdownOpen, setIsDropdownOpen] = useState(false); - - useEffect(() => { - // Generate the unified diff format - const generatedDiff = createTwoFilesPatch( - filePath, - filePath, - oldContent, - newContent, - 'old version', - 'new version' - ); - - // Parse the unified diff to an internal data structure - const diffJson = parse(generatedDiff); - - // Use diff2html to generate the side-by-side HTML - const configuration = { - drawFileList: true, - matching: 'lines', - outputFormat: 'side-by-side' // Crucial for side-by-side view - }; - const htmlOutput = html(diffJson, configuration); - setDiffHtml(htmlOutput); - }, [oldContent, newContent, filePath]); - - if (!diffHtml) return null; - - const handleDownload = (fileType) => { - let content, filename; - - switch (fileType) { - case 'diff': - content = createTwoFilesPatch( - filePath, - filePath, - oldContent, - newContent, - 'old version', - 'new version' - ); - filename = `${filePath.split('/').pop()}_changes.diff`; - break; - case 'old': - content = oldContent; - filename = `${filePath.split('/').pop()}_old.txt`; - break; - case 'new': - content = newContent; - filename = `${filePath.split('/').pop()}_new.txt`; - break; - default: - return; - } - - const blob = new Blob([content], { type: 'text/plain' }); - const url = URL.createObjectURL(blob); - const a = document.createElement('a'); - a.href = url; - a.download = filename; - document.body.appendChild(a); - a.click(); - document.body.removeChild(a); - URL.revokeObjectURL(url); - setIsDropdownOpen(false); // Close the dropdown after download - }; - - return ( -
-
-
-

Changes in {filePath}

-
-
- - {isDropdownOpen && ( -
-
- - - -
-
- )} -
- -
-
-
-
-
- ); -}; - -export default DiffViewer; \ No newline at end of file diff --git a/ui/client-app/src/components/FileList.js b/ui/client-app/src/components/FileList.js deleted file mode 100644 index 80c6d9c..0000000 --- a/ui/client-app/src/components/FileList.js +++ /dev/null @@ -1,35 +0,0 @@ -// FileListComponent.jsx -import React from "react"; -import ReactMarkdown from 'react-markdown'; - -const FileListComponent = ({ code_changes, onFileClick }) => { - const filesArray = code_changes ? Object.keys(code_changes).map(filepath => ({ - filepath, - ...code_changes[filepath] - })) : []; - - return ( -
-
Files:
- {filesArray.map((file, index) => ( -
onFileClick(file)} - > -
- - - - {file.filepath} -
-
- {file.reasoning} -
-
- ))} -
- ); -}; - -export default FileListComponent; \ No newline at end of file