Преглед на файлове

refactor: move leftnav and agent controls to new play bar (#1317)

* refactor: move leftnav and agent controls to new play bar

* layout change
Alex Bäuerle преди 1 година
родител
ревизия
f40e91b41b
променени са 3 файла, в които са добавени 53 реда и са изтрити 53 реда
  1. 29 25
      frontend/src/App.tsx
  2. 24 22
      frontend/src/components/AgentControlBar.tsx
  3. 0 6
      frontend/src/components/ChatInterface.tsx

+ 29 - 25
frontend/src/App.tsx

@@ -1,29 +1,35 @@
+import { useDisclosure } from "@nextui-org/react";
 import React, { useEffect, useState } from "react";
-import "./App.css";
 import { Toaster } from "react-hot-toast";
-import { useDisclosure } from "@nextui-org/react";
 import CogTooth from "#/assets/cog-tooth";
 import ChatInterface from "#/components/ChatInterface";
 import Errors from "#/components/Errors";
 import { Container, Orientation } from "#/components/Resizable";
-import Terminal from "#/components/Terminal";
 import Workspace from "#/components/Workspace";
+import LoadPreviousSessionModal from "#/components/modals/load-previous-session/LoadPreviousSessionModal";
+import SettingsModal from "#/components/modals/settings/SettingsModal";
 import { fetchMsgTotal } from "#/services/session";
 import { initializeAgent } from "#/services/settingsService";
 import Socket from "#/services/socket";
 import { ResFetchMsgTotal } from "#/types/ResponseType";
-import SettingsModal from "#/components/modals/settings/SettingsModal";
-import LoadPreviousSessionModal from "#/components/modals/load-previous-session/LoadPreviousSessionModal";
+import "./App.css";
+import AgentControlBar from "./components/AgentControlBar";
+import AgentStatusBar from "./components/AgentStatusBar";
+import Terminal from "./components/Terminal";
 
 interface Props {
   setSettingOpen: (isOpen: boolean) => void;
 }
 
-function LeftNav({ setSettingOpen }: Props): JSX.Element {
+function Controls({ setSettingOpen }: Props): JSX.Element {
   return (
-    <div className="flex flex-col h-full p-4 bg-neutral-900 w-16 items-center shrink-0">
+    <div className="flex w-full p-4 bg-neutral-900 items-center shrink-0 justify-between">
+      <div className="flex items-center gap-4">
+        <AgentControlBar />
+      </div>
+      <AgentStatusBar />
       <div
-        className="mt-auto cursor-pointer hover:opacity-80"
+        className="cursor-pointer hover:opacity-80 transition-all"
         onClick={() => setSettingOpen(true)}
       >
         <CogTooth />
@@ -71,35 +77,33 @@ function App(): JSX.Element {
     Socket.registerCallback("open", [getMsgTotal]);
 
     getMsgTotal();
+    // eslint-disable-next-line react-hooks/exhaustive-deps
   }, []);
 
   return (
     <div className="h-screen w-screen flex flex-col">
       <div className="flex grow bg-neutral-900 text-white min-h-0">
-        <LeftNav setSettingOpen={onSettingsModalOpen} />
         <Container
-          orientation={Orientation.VERTICAL}
-          className="grow p-3 py-3 pr-3 min-w-0"
-          initialSize={window.innerHeight - 300}
-          firstChild={
+          orientation={Orientation.HORIZONTAL}
+          className="grow h-full min-h-0 min-w-0 px-3 pt-3"
+          initialSize={500}
+          firstChild={<ChatInterface />}
+          firstClassName="min-w-[500px] rounded-xl overflow-hidden border border-neutral-600"
+          secondChild={
             <Container
-              orientation={Orientation.HORIZONTAL}
+              orientation={Orientation.VERTICAL}
               className="grow h-full min-h-0 min-w-0"
-              initialSize={500}
-              firstChild={<ChatInterface />}
-              firstClassName="min-w-[500px] rounded-xl overflow-hidden border border-neutral-600"
-              secondChild={<Workspace />}
-              secondClassName="flex flex-col overflow-hidden rounded-xl bg-neutral-800 border border-neutral-600 grow min-w-[500px] min-w-[500px]"
+              initialSize={window.innerHeight - 300}
+              firstChild={<Workspace />}
+              firstClassName="min-h-72 rounded-xl border border-neutral-600 bg-neutral-800 flex flex-col overflow-hidden"
+              secondChild={<Terminal />}
+              secondClassName="min-h-72 rounded-xl border border-neutral-600 bg-neutral-800"
             />
           }
-          firstClassName="min-h-72"
-          secondChild={<Terminal key="terminal" />}
-          secondClassName="min-h-72 bg-neutral-800 rounded-xl border border-neutral-600 flex flex-col"
+          secondClassName="flex flex-col overflow-hidden grow min-w-[500px]"
         />
       </div>
-      {/* This div is for the footer that will be added later
-      <div className="h-8 w-full border-t border-border px-2" />
-      */}
+      <Controls setSettingOpen={onSettingsModalOpen} />
       <SettingsModal
         isOpen={settingsModalIsOpen}
         onOpenChange={onSettingsModalOpenChange}

+ 24 - 22
frontend/src/components/AgentControlBar.tsx

@@ -1,4 +1,4 @@
-import { Button, ButtonGroup, Tooltip } from "@nextui-org/react";
+import { Tooltip } from "@nextui-org/react";
 import React, { useEffect } from "react";
 import { useSelector } from "react-redux";
 import ArrowIcon from "#/assets/arrow";
@@ -39,35 +39,39 @@ const IgnoreTaskStateMap: { [k: string]: AgentTaskState[] } = {
 };
 
 interface ButtonProps {
-  isLoading: boolean;
   isDisabled: boolean;
   content: string;
   action: AgentTaskAction;
   handleAction: (action: AgentTaskAction) => void;
+  large?: boolean;
 }
 
 function ActionButton({
-  isLoading = false,
   isDisabled = false,
   content,
   action,
   handleAction,
   children,
+  large,
 }: React.PropsWithChildren<ButtonProps>): React.ReactNode {
   return (
     <Tooltip content={content} closeDelay={100}>
-      <Button
-        isIconOnly
+      <button
         onClick={() => handleAction(action)}
-        isLoading={isLoading}
-        isDisabled={isDisabled}
+        disabled={isDisabled}
+        className={`${large ? "rounded-full bg-neutral-800 p-3" : ""} hover:opacity-80 transition-all`}
+        type="button"
       >
         {children}
-      </Button>
+      </button>
     </Tooltip>
   );
 }
 
+ActionButton.defaultProps = {
+  large: false,
+};
+
 function AgentControlBar() {
   const { curTaskState } = useSelector((state: RootState) => state.agent);
   const [desiredState, setDesiredState] = React.useState(AgentTaskState.INIT);
@@ -107,20 +111,9 @@ function AgentControlBar() {
   }, [curTaskState]);
 
   return (
-    <ButtonGroup size="sm" variant="ghost">
-      <ActionButton
-        isLoading={false}
-        isDisabled={isLoading}
-        content="Restart a new agent task"
-        action={AgentTaskAction.STOP}
-        handleAction={handleAction}
-      >
-        <ArrowIcon />
-      </ActionButton>
-
+    <div className="flex items-center gap-3">
       {curTaskState === AgentTaskState.PAUSED ? (
         <ActionButton
-          isLoading={isLoading}
           isDisabled={
             isLoading ||
             IgnoreTaskStateMap[AgentTaskAction.RESUME].includes(curTaskState)
@@ -128,12 +121,12 @@ function AgentControlBar() {
           content="Resume the agent task"
           action={AgentTaskAction.RESUME}
           handleAction={handleAction}
+          large
         >
           <PlayIcon />
         </ActionButton>
       ) : (
         <ActionButton
-          isLoading={isLoading}
           isDisabled={
             isLoading ||
             IgnoreTaskStateMap[AgentTaskAction.PAUSE].includes(curTaskState)
@@ -141,11 +134,20 @@ function AgentControlBar() {
           content="Pause the agent task"
           action={AgentTaskAction.PAUSE}
           handleAction={handleAction}
+          large
         >
           <PauseIcon />
         </ActionButton>
       )}
-    </ButtonGroup>
+      <ActionButton
+        isDisabled={isLoading}
+        content="Restart a new agent task"
+        action={AgentTaskAction.STOP}
+        handleAction={handleAction}
+      >
+        <ArrowIcon />
+      </ActionButton>
+    </div>
   );
 }
 

+ 0 - 6
frontend/src/components/ChatInterface.tsx

@@ -11,8 +11,6 @@ import {
 } from "#/services/chatService";
 import { Message } from "#/state/chatSlice";
 import { RootState } from "#/store";
-import AgentControlBar from "./AgentControlBar";
-import AgentStatusBar from "./AgentStatusBar";
 import ChatInput from "./ChatInput";
 
 interface IChatBubbleProps {
@@ -124,10 +122,6 @@ function ChatInterface(): JSX.Element {
         Chat
       </div>
       <MessageList />
-      <div className="flex justify-between items-center px-4">
-        <AgentStatusBar />
-        <AgentControlBar />
-      </div>
       <ChatInput disabled={!initialized} onSendMessage={sendChatMessage} />
     </div>
   );