Przeglądaj źródła

feat(frontend): Add file picker to choose the working directory #221 (#289)

Add a file picker feature to top of the chat window.

Now a user can select the directory to work with.

Once a directory is chosen the user has the option to edit the directory also.(i.e choose another directory).
Yashwanth S C 1 rok temu
rodzic
commit
f38bbf9261

+ 28 - 0
frontend/src/components/ChatInterface.css

@@ -95,3 +95,31 @@
 .input-box button:hover {
   background-color: transparent;
 }
+.custom-file-input {
+  display: inline-block;
+  padding: 10px 20px;
+  font-size: 16px;
+  font-weight: bold;
+  color: white;
+  background-color: rgb(62, 62, 62);
+  border: none;
+  border-radius: 5px;
+  cursor: pointer;
+}
+
+.custom-file-input:hover {
+  background-color: rgb(70, 70, 70);
+}
+
+.custom-file-input input {
+  display: none;
+}
+.selected-directory {
+  display: flex;
+  justify-content: space-between;
+  padding: 10px 20px;
+  background-color: rgb(62, 62, 62);
+}
+.selected-directory > button:hover {
+  text-decoration: underline;
+}

+ 45 - 4
frontend/src/components/ChatInterface.tsx

@@ -1,10 +1,10 @@
-import React, { useEffect, useRef, useState } from "react";
+import React, { ChangeEvent, useEffect, useRef, useState } from "react";
 import { useSelector } from "react-redux";
-import "./ChatInterface.css";
-import userAvatar from "../assets/user-avatar.png";
 import assistantAvatar from "../assets/assistant-avatar.png";
-import { RootState } from "../store";
+import userAvatar from "../assets/user-avatar.png";
 import { sendChatMessage } from "../services/chatService";
+import { RootState } from "../store";
+import "./ChatInterface.css";
 
 function MessageList(): JSX.Element {
   const messagesEndRef = useRef<HTMLDivElement>(null);
@@ -47,6 +47,8 @@ function InitializingStatus(): JSX.Element {
 function ChatInterface(): JSX.Element {
   const { initialized } = useSelector((state: RootState) => state.task);
   const [inputMessage, setInputMessage] = useState("");
+  const [selectedDirectory, setSelectedDirectory] = useState("");
+  const fileInputRef = useRef<HTMLInputElement>(null);
 
   const handleSendMessage = () => {
     if (inputMessage.trim() !== "") {
@@ -55,8 +57,47 @@ function ChatInterface(): JSX.Element {
     }
   };
 
+  const handleDirectorySelected = (event: ChangeEvent<HTMLInputElement>) => {
+    const { files } = event.target;
+    if (files && files.length > 0) {
+      const directory = files[0].webkitRelativePath.split("/")[0];
+      setSelectedDirectory(directory);
+    }
+  };
+
+  const handleEditDirectory = () => {
+    if (fileInputRef.current) {
+      fileInputRef.current.value = ""; // Clear the file input value
+      fileInputRef.current.click(); // Trigger the file picker dialog
+    }
+  };
+
   return (
     <div className="chat-interface">
+      <label
+        htmlFor="directoryInput"
+        className="custom-file-input"
+        style={{ display: selectedDirectory ? "none" : "block" }}
+      >
+        Choose Directory
+        <input
+          id="directoryInput"
+          type="file"
+          capture="directory"
+          webkitdirectory=""
+          onChange={handleDirectorySelected}
+          ref={fileInputRef}
+          style={{ display: "none" }}
+        />
+      </label>
+      {selectedDirectory && (
+        <div className="selected-directory">
+          Selected Directory: {selectedDirectory}
+          <button type="button" onClick={handleEditDirectory}>
+            Edit
+          </button>
+        </div>
+      )}
       {initialized ? <MessageList /> : <InitializingStatus />}
       <div className="input-container">
         <div className="input-box">