Ver Fonte

fix: fix some of the styling to more closely match figma (#927)

* fix: fix some of the styling to more closely match figma

* overflow
Alex Bäuerle há 1 ano atrás
pai
commit
224ee7d1f8

+ 5 - 1
frontend/src/components/ChatInterface.tsx

@@ -1,5 +1,6 @@
 import { Card, CardBody } from "@nextui-org/react";
 import React, { useEffect, useRef } from "react";
+import { IoMdChatbubbles } from "react-icons/io";
 import { useSelector } from "react-redux";
 import { useTypingEffect } from "../hooks/useTypingEffect";
 import {
@@ -116,7 +117,10 @@ function ChatInterface(): JSX.Element {
 
   return (
     <div className="flex flex-col h-full p-0 bg-neutral-800">
-      <div className="border-b border-neutral-600 text-sm px-4 py-2">Chat</div>
+      <div className="flex items-center gap-2 border-b border-neutral-600 text-sm px-4 py-2">
+        <IoMdChatbubbles />
+        Chat
+      </div>
       <MessageList />
       {initialized ? null : <AgentStatusBar />}
       <Input />

+ 20 - 27
frontend/src/components/CodeEditor.tsx

@@ -1,11 +1,10 @@
 import Editor, { Monaco } from "@monaco-editor/react";
+import { Tab, Tabs } from "@nextui-org/react";
 import type { editor } from "monaco-editor";
 import React, { useState } from "react";
-import { Tabs, Tab } from "@nextui-org/react";
 import { useSelector } from "react-redux";
 import { RootState } from "../store";
 import Files from "./Files";
-import { cn } from "../utils/utils";
 
 function CodeEditor(): JSX.Element {
   const [selectedFileName, setSelectedFileName] = useState("welcome");
@@ -31,24 +30,19 @@ function CodeEditor(): JSX.Element {
   };
 
   return (
-    <div
-      className={`${cn(
-        explorerOpen ? "grid-cols-[250px_auto]" : "grid-cols-[50px_auto]",
-      )} grid h-full bg-neutral-900 transition-all duration-500 ease-in-out`}
-    >
-      <div>
-        <Files
-          setSelectedFileName={setSelectedFileName}
-          setExplorerOpen={setExplorerOpen}
-          explorerOpen={explorerOpen}
-        />
-      </div>
-      <div>
+    <div className="flex h-full w-full bg-neutral-900 transition-all duration-500 ease-in-out">
+      <Files
+        setSelectedFileName={setSelectedFileName}
+        setExplorerOpen={setExplorerOpen}
+        explorerOpen={explorerOpen}
+      />
+      <div className="flex flex-col min-h-0 w-full">
         <Tabs
           disableCursorAnimation
           classNames={{
+            base: "border-b border-divider",
             tabList:
-              "w-full relative rounded-none bg-neutral-900 p-0 border-r border-divider",
+              "w-full relative rounded-none bg-neutral-900 p-0 border-divider",
             cursor: "w-full bg-neutral-600 rounded-none",
             tab: "max-w-fit px-4 h-[36px]",
             tabContent: "group-data-[selected=true]:text-neutral-50 ",
@@ -62,18 +56,17 @@ function CodeEditor(): JSX.Element {
                 : selectedFileName.toLocaleLowerCase()
             }
             title={!selectedFileName ? "Welcome" : selectedFileName}
-          >
-            <div>
-              <Editor
-                height="100vh"
-                defaultLanguage="python"
-                defaultValue="# Welcome to OpenDevin!"
-                value={code}
-                onMount={handleEditorDidMount}
-              />
-            </div>
-          </Tab>
+          />
         </Tabs>
+        <div className="flex grow">
+          <Editor
+            height="100%"
+            defaultLanguage="python"
+            defaultValue="# Welcome to OpenDevin!"
+            value={code}
+            onMount={handleEditorDidMount}
+          />
+        </div>
       </div>
     </div>
   );

+ 3 - 3
frontend/src/components/Files.tsx

@@ -1,7 +1,7 @@
+import { Accordion, AccordionItem, Button } from "@nextui-org/react";
 import React, { useEffect } from "react";
 import TreeView, { flattenTree } from "react-accessible-treeview";
 import { AiOutlineFolder } from "react-icons/ai";
-import { Accordion, AccordionItem, Button } from "@nextui-org/react";
 import {
   TbLayoutSidebarLeftCollapseFilled,
   TbLayoutSidebarRightCollapseFilled,
@@ -13,8 +13,8 @@ import { useSelector } from "react-redux";
 import { getWorkspace, selectFile } from "../services/fileService";
 import { setCode, updateWorkspace } from "../state/codeSlice";
 import store, { RootState } from "../store";
-import FolderIcon from "./FolderIcon";
 import FileIcon from "./FileIcons";
+import FolderIcon from "./FolderIcon";
 
 interface FilesProps {
   setSelectedFileName: React.Dispatch<React.SetStateAction<string>>;
@@ -57,7 +57,7 @@ function Files({
     );
   }
   return (
-    <div className="bg-neutral-800 h-full border-r-1 border-r-neutral-600 flex flex-col">
+    <div className="bg-neutral-800 h-full border-r-1 border-r-neutral-600 flex flex-col w-[250px]">
       <div className="flex p-2 items-center justify-between ">
         <Accordion className="px-0" defaultExpandedKeys={["1"]} isCompact>
           <AccordionItem

+ 4 - 1
frontend/src/components/Input.tsx

@@ -1,6 +1,7 @@
 import { Textarea } from "@nextui-org/react";
 import React, { ChangeEvent, KeyboardEvent, useState } from "react";
 import { useTranslation } from "react-i18next";
+import { VscSend } from "react-icons/vsc";
 import { useSelector } from "react-redux";
 import { twMerge } from "tailwind-merge";
 import useInputComposition from "../hooks/useInputComposition";
@@ -46,6 +47,7 @@ function Input() {
       <Textarea
         className="py-4 px-4"
         classNames={{
+          inputWrapper: "bg-neutral-700",
           input: "pr-16 py-2",
         }}
         value={inputMessage}
@@ -66,8 +68,9 @@ function Input() {
         )}
         onClick={handleSendMessage}
         disabled={!initialized}
+        aria-label="Send message"
       >
-        {t(I18nKey.CHAT_INTERFACE$INPUT_SEND_MESSAGE_BUTTON_CONTENT)}
+        <VscSend />
       </button>
     </div>
   );

+ 6 - 4
frontend/src/components/Terminal.tsx

@@ -1,12 +1,13 @@
-import React, { useEffect, useRef } from "react";
 import { IDisposable, Terminal as XtermTerminal } from "@xterm/xterm";
 import "@xterm/xterm/css/xterm.css";
+import React, { useEffect, useRef } from "react";
+import { VscTerminal } from "react-icons/vsc";
 import { useSelector } from "react-redux";
 import { FitAddon } from "xterm-addon-fit";
-import ActionType from "../types/ActionType";
-import ObservationType from "../types/ObservationType";
 import Socket from "../services/socket";
 import { RootState } from "../store";
+import ActionType from "../types/ActionType";
+import ObservationType from "../types/ObservationType";
 
 class JsonWebsocketAddon {
   _disposables: IDisposable[];
@@ -100,7 +101,8 @@ function Terminal(): JSX.Element {
 
   return (
     <div className="flex flex-col h-full">
-      <div className="px-4 py-2 text-sm border-b border-neutral-600">
+      <div className="flex items-center gap-2 px-4 py-2 text-sm border-b border-neutral-600">
+        <VscTerminal />
         Terminal
       </div>
       <div className="grow p-2 flex min-h-0">

+ 14 - 20
frontend/src/components/Workspace.tsx

@@ -1,8 +1,8 @@
 import { Tab, Tabs } from "@nextui-org/react";
 import React, { useMemo, useState } from "react";
 import { useTranslation } from "react-i18next";
-import { FaCode } from "react-icons/fa6";
 import { IoIosGlobe } from "react-icons/io";
+import { VscCode } from "react-icons/vsc";
 import Calendar from "../assets/calendar";
 import { I18nKey } from "../i18n/declaration";
 import { AllTabs, TabOption, TabType } from "../types/TabOption";
@@ -23,7 +23,7 @@ function Workspace() {
       },
       [TabOption.CODE]: {
         name: t(I18nKey.WORKSPACE$CODE_EDITOR_TAB_LABEL),
-        icon: <FaCode size={18} />,
+        icon: <VscCode size={18} />,
         component: <CodeEditor key="code" />,
       },
       [TabOption.BROWSER]: {
@@ -36,31 +36,31 @@ function Workspace() {
   );
 
   return (
-    <>
+    <div className="flex flex-col min-h-0 grow">
       <div
         role="tablist"
-        className="tabs tabs-bordered tabs-lg border-b border-neutral-600"
+        className="tabs tabs-bordered tabs-lg border-b border-neutral-600 flex"
       >
         <Tabs
           disableCursorAnimation
           classNames={{
+            base: "w-full",
             tabList:
-              "w-full relative rounded-none bg-neutral-800 p-0 border-divider gap-0 h-[36px]",
-            cursor: "w-full bg-neutral-800  rounded-none",
-            tab: " rounded-none border-neutral-600 border-r-[1px] border-r",
+              "w-full relative rounded-none bg-neutral-900 p-0 gap-0 h-[36px] flex",
+            tab: "rounded-none border-neutral-600 data-[selected=true]:bg-neutral-800",
             tabContent: "group-data-[selected=true]:text-neutral-50",
           }}
-          variant="light"
           size="lg"
           onSelectionChange={(v) => {
             setActiveTab(v as TabType);
           }}
         >
-          {AllTabs.map((tab) => (
+          {AllTabs.map((tab, index) => (
             <Tab
               key={tab}
+              className={`flex-grow ${index + 1 === AllTabs.length ? "" : "border-r"}`}
               title={
-                <div className="flex items-center space-x-2 justify-center text-xs">
+                <div className="flex grow items-center gap-2 justify-center text-xs">
                   {tabData[tab].icon}
                   <span>{tabData[tab].name}</span>
                 </div>
@@ -69,16 +69,10 @@ function Workspace() {
           ))}
         </Tabs>
       </div>
-      {Object.keys(tabData).map((tab) => (
-        <div
-          className="h-full w-full bg-neutral-800"
-          key={tab}
-          hidden={activeTab !== tab}
-        >
-          {tabData[tab as TabType].component}
-        </div>
-      ))}
-    </>
+      <div className="grow w-full bg-neutral-800 flex min-h-0">
+        {tabData[activeTab as TabType].component}
+      </div>
+    </div>
   );
 }
 export default Workspace;