Skip to content

Commit

Permalink
refactor(frontend): settings and friends (#1400)
Browse files Browse the repository at this point in the history
* refactor settings and friends

* extend base modal to support disabled property

* extend settings handler to change language via i18next

* remove unused settings.d.ts

---------

Co-authored-by: Jim Su <jimsu@protonmail.com>
Co-authored-by: Engel Nyst <enyst@users.noreply.github.com>
  • Loading branch information
3 people committed Apr 29, 2024
1 parent 24b7192 commit 8954855
Show file tree
Hide file tree
Showing 17 changed files with 543 additions and 338 deletions.
5 changes: 3 additions & 2 deletions frontend/src/App.tsx
Expand Up @@ -9,13 +9,14 @@ 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 "./App.css";
import AgentControlBar from "./components/AgentControlBar";
import AgentStatusBar from "./components/AgentStatusBar";
import Terminal from "./components/terminal/Terminal";
import { initializeAgent } from "./services/agent";
import { getSettings } from "./services/settings";

interface Props {
setSettingOpen: (isOpen: boolean) => void;
Expand Down Expand Up @@ -72,7 +73,7 @@ function App(): JSX.Element {
if (initOnce) return;
initOnce = true;

initializeAgent();
initializeAgent(getSettings());

Socket.registerCallback("open", [getMsgTotal]);

Expand Down
9 changes: 9 additions & 0 deletions frontend/src/api/index.ts
@@ -0,0 +1,9 @@
export async function fetchModels() {
const response = await fetch(`/api/litellm-models`);
return response.json();
}

export async function fetchAgents() {
const response = await fetch(`/api/agents`);
return response.json();
}
36 changes: 36 additions & 0 deletions frontend/src/components/modals/base-modal/BaseModal.test.tsx
Expand Up @@ -96,6 +96,42 @@ describe("BaseModal", () => {
expect(screen.getByText("Children")).toBeInTheDocument();
});

it("should disable the action given the condition", () => {
const { rerender } = render(
<BaseModal
isOpen
onOpenChange={vi.fn}
title="Settings"
actions={[
{
label: "Save",
action: () => {},
isDisabled: true,
},
]}
/>,
);

expect(screen.getByText("Save")).toBeDisabled();

rerender(
<BaseModal
isOpen
onOpenChange={vi.fn}
title="Settings"
actions={[
{
label: "Save",
action: () => {},
isDisabled: false,
},
]}
/>,
);

expect(screen.getByText("Save")).not.toBeDisabled();
});

it.skip("should not close if the backdrop or escape key is pressed", () => {
const onOpenChangeMock = vi.fn();
render(
Expand Down
30 changes: 17 additions & 13 deletions frontend/src/components/modals/base-modal/FooterContent.tsx
Expand Up @@ -3,6 +3,7 @@ import React from "react";

export interface Action {
action: () => void;
isDisabled?: boolean;
label: string;
className?: string;
closeAfterAction?: boolean;
Expand All @@ -16,19 +17,22 @@ interface FooterContentProps {
export function FooterContent({ actions, closeModal }: FooterContentProps) {
return (
<>
{actions.map(({ action, label, className, closeAfterAction }) => (
<Button
key={label}
type="button"
onClick={() => {
action();
if (closeAfterAction) closeModal();
}}
className={className}
>
{label}
</Button>
))}
{actions.map(
({ action, isDisabled, label, className, closeAfterAction }) => (
<Button
key={label}
type="button"
isDisabled={isDisabled}
onClick={() => {
action();
if (closeAfterAction) closeModal();
}}
className={className}
>
{label}
</Button>
),
)}
</>
);
}
25 changes: 18 additions & 7 deletions frontend/src/components/modals/settings/SettingsForm.test.tsx
Expand Up @@ -4,15 +4,22 @@ import React from "react";
import { renderWithProviders } from "test-utils";
import AgentTaskState from "#/types/AgentTaskState";
import SettingsForm from "./SettingsForm";
import { Settings } from "#/services/settings";

const onModelChangeMock = vi.fn();
const onAgentChangeMock = vi.fn();
const onLanguageChangeMock = vi.fn();

const renderSettingsForm = (settings: Partial<Settings>) => {
const renderSettingsForm = (settings?: Settings) => {
renderWithProviders(
<SettingsForm
settings={settings}
settings={
settings || {
LLM_MODEL: "model1",
AGENT: "agent1",
LANGUAGE: "en",
}
}
models={["model1", "model2", "model3"]}
agents={["agent1", "agent2", "agent3"]}
onModelChange={onModelChangeMock}
Expand All @@ -24,7 +31,7 @@ const renderSettingsForm = (settings: Partial<Settings>) => {

describe("SettingsForm", () => {
it("should display the first values in the array by default", () => {
renderSettingsForm({});
renderSettingsForm();

const modelInput = screen.getByRole("combobox", { name: "model" });
const agentInput = screen.getByRole("combobox", { name: "agent" });
Expand Down Expand Up @@ -54,7 +61,11 @@ describe("SettingsForm", () => {
it("should disable settings while task is running", () => {
renderWithProviders(
<SettingsForm
settings={{}}
settings={{
LLM_MODEL: "model1",
AGENT: "agent1",
LANGUAGE: "en",
}}
models={["model1", "model2", "model3"]}
agents={["agent1", "agent2", "agent3"]}
onModelChange={onModelChangeMock}
Expand All @@ -74,7 +85,7 @@ describe("SettingsForm", () => {

describe("onChange handlers", () => {
it("should call the onModelChange handler when the model changes", () => {
renderSettingsForm({});
renderSettingsForm();

const modelInput = screen.getByRole("combobox", { name: "model" });
act(() => {
Expand All @@ -90,7 +101,7 @@ describe("SettingsForm", () => {
});

it("should call the onAgentChange handler when the agent changes", () => {
renderSettingsForm({});
renderSettingsForm();

const agentInput = screen.getByRole("combobox", { name: "agent" });
act(() => {
Expand All @@ -106,7 +117,7 @@ describe("SettingsForm", () => {
});

it("should call the onLanguageChange handler when the language changes", () => {
renderSettingsForm({});
renderSettingsForm();

const languageInput = screen.getByRole("combobox", { name: "language" });
act(() => {
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/components/modals/settings/SettingsForm.tsx
Expand Up @@ -6,9 +6,10 @@ import { I18nKey } from "../../../i18n/declaration";
import { RootState } from "../../../store";
import AgentTaskState from "../../../types/AgentTaskState";
import { AutocompleteCombobox } from "./AutocompleteCombobox";
import { Settings } from "#/services/settings";

interface SettingsFormProps {
settings: Partial<Settings>;
settings: Settings;
models: string[];
agents: string[];

Expand Down

0 comments on commit 8954855

Please sign in to comment.