Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issue #5894: Make it possible to collapse the right-hand side of the openhands screen #5896

Closed
wants to merge 15 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: trailing-whitespace
exclude: docs/modules/python
- id: end-of-file-fixer
exclude: docs/modules/python
- id: check-yaml
- id: debug-statements

- repo: https://github.com/tox-dev/pyproject-fmt
rev: 1.7.0
hooks:
- id: pyproject-fmt
- repo: https://github.com/abravalheri/validate-pyproject
rev: v0.16
hooks:
- id: validate-pyproject

- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.4.1
hooks:
# Run the linter.
- id: ruff
entry: ruff check --config dev_config/python/ruff.toml
types_or: [python, pyi, jupyter]
args: [--fix]
# Run the formatter.
- id: ruff-format
entry: ruff format --config dev_config/python/ruff.toml
types_or: [python, pyi, jupyter]

- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.9.0
hooks:
- id: mypy
additional_dependencies:
[types-requests, types-setuptools, types-pyyaml, types-toml]
entry: mypy --config-file dev_config/python/mypy.ini openhands/
always_run: true
pass_filenames: false
35 changes: 35 additions & 0 deletions frontend/__tests__/components/workspace-toggle.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { render, screen, fireEvent } from "@testing-library/react";
import { describe, it, expect, vi } from "vitest";
import { ToggleWorkspaceIconButton } from "#/components/shared/buttons/toggle-workspace-icon-button";

describe("Workspace Toggle", () => {
it("should render toggle button with correct icon and label", () => {
const onClickMock = vi.fn();

// Test initial state (workspace visible)
const { rerender } = render(
<ToggleWorkspaceIconButton onClick={onClickMock} isHidden={false} />
);

const button = screen.getByTestId("toggle");
expect(button).toBeInTheDocument();
expect(button).toHaveAttribute("aria-label", "Close workspace");

// Test hidden state
rerender(
<ToggleWorkspaceIconButton onClick={onClickMock} isHidden={true} />
);
expect(button).toHaveAttribute("aria-label", "Open workspace");
});

it("should call onClick handler when clicked", () => {
const onClickMock = vi.fn();
render(
<ToggleWorkspaceIconButton onClick={onClickMock} isHidden={false} />
);

const button = screen.getByTestId("toggle");
fireEvent.click(button);
expect(onClickMock).toHaveBeenCalledTimes(1);
});
});
2 changes: 1 addition & 1 deletion frontend/src/components/features/chat/chat-suggestions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ interface ChatSuggestionsProps {

export function ChatSuggestions({ onSuggestionsClick }: ChatSuggestionsProps) {
return (
<div className="flex flex-col gap-6 h-full px-4 items-center justify-center">
<div className="flex flex-col gap-6 h-full px-4 items-center justify-center w-full">
<div className="flex flex-col items-center p-4 bg-neutral-700 rounded-xl w-full">
<BuildIt width={45} height={54} />
<span className="font-semibold text-[20px] leading-6 -tracking-[0.01em] gap-1">
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/components/shared/buttons/icon-button.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Button } from "@nextui-org/react";
import React, { MouseEventHandler, ReactElement } from "react";
import React, { ReactElement } from "react";

export interface IconButtonProps {
icon: ReactElement;
onClick: MouseEventHandler<HTMLButtonElement>;
onClick: () => void;
ariaLabel: string;
testId?: string;
}
Expand All @@ -18,7 +18,7 @@ export function IconButton({
<Button
type="button"
variant="flat"
onClick={onClick}
onPress={onClick}
className="cursor-pointer text-[12px] bg-transparent aspect-square px-0 min-w-[20px] h-[20px]"
aria-label={ariaLabel}
data-testid={testId}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ export function ToggleWorkspaceIconButton({
<IconButton
icon={
isHidden ? (
<IoIosArrowForward
<IoIosArrowBack
size={20}
className="text-neutral-400 hover:text-neutral-100 transition"
/>
) : (
<IoIosArrowBack
<IoIosArrowForward
size={20}
className="text-neutral-400 hover:text-neutral-100 transition"
/>
Expand Down
18 changes: 15 additions & 3 deletions frontend/src/routes/_oh.app/route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import Security from "#/components/shared/modals/security/security";
import { CountBadge } from "#/components/layout/count-badge";
import { TerminalStatusLabel } from "#/components/features/terminal/terminal-status-label";
import { ToggleWorkspaceIconButton } from "#/components/shared/buttons/toggle-workspace-icon-button";

function AppContent() {
const { gitHubToken } = useAuth();
Expand Down Expand Up @@ -62,6 +63,12 @@
dispatch(clearJupyter());
});

const [isWorkspaceHidden, setIsWorkspaceHidden] = React.useState(false);

const toggleWorkspace = React.useCallback(() => {
setIsWorkspaceHidden((prev) => !prev);
}, []);

const {
isOpen: securityModalIsOpen,
onOpen: onSecurityModalOpen,
Expand All @@ -73,11 +80,16 @@
<EventHandler>
<div className="flex flex-col h-full gap-3">
<div className="flex h-full overflow-auto gap-3">
<Container className="w-full md:w-[390px] max-h-full relative">
<ChatInterface />
<Container className={`w-full ${isWorkspaceHidden ? "" : "md:w-[390px]"} max-h-full relative`}>

Check failure on line 83 in frontend/src/routes/_oh.app/route.tsx

View workflow job for this annotation

GitHub Actions / Lint frontend

Replace `·className={`w-full·${isWorkspaceHidden·?·""·:·"md:w-[390px]"}·max-h-full·relative`}` with `⏎··············className={`w-full·${isWorkspaceHidden·?·""·:·"md:w-[390px]"}·max-h-full·relative`}⏎············`
<div className="flex items-center justify-between">
<ChatInterface />
<div className="hidden md:block absolute right-2 top-2">
<ToggleWorkspaceIconButton onClick={toggleWorkspace} isHidden={isWorkspaceHidden} />

Check failure on line 87 in frontend/src/routes/_oh.app/route.tsx

View workflow job for this annotation

GitHub Actions / Lint frontend

Replace `·onClick={toggleWorkspace}·isHidden={isWorkspaceHidden}` with `⏎····················onClick={toggleWorkspace}⏎····················isHidden={isWorkspaceHidden}⏎·················`
</div>
</div>
</Container>

<div className="hidden md:flex flex-col grow gap-3">
<div className={`hidden md:flex flex-col grow gap-3 transition-all duration-300 ${isWorkspaceHidden ? "w-0 opacity-0 overflow-hidden" : ""}`}>

Check failure on line 92 in frontend/src/routes/_oh.app/route.tsx

View workflow job for this annotation

GitHub Actions / Lint frontend

Replace `·className={`hidden·md:flex·flex-col·grow·gap-3·transition-all·duration-300·${isWorkspaceHidden·?·"w-0·opacity-0·overflow-hidden"·:·""}`}` with `⏎··············className={`hidden·md:flex·flex-col·grow·gap-3·transition-all·duration-300·${isWorkspaceHidden·?·"w-0·opacity-0·overflow-hidden"·:·""}`}⏎············`
<Container
className="h-2/3"
labels={[
Expand Down
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ reportlab = "*"
[tool.coverage.run]
concurrency = ["gevent"]


[tool.poetry.group.runtime.dependencies]
jupyterlab = "*"
notebook = "*"
Expand Down Expand Up @@ -129,6 +130,7 @@ ignore = ["D1"]
[tool.ruff.lint.pydocstyle]
convention = "google"


[tool.poetry.group.evaluation.dependencies]
streamlit = "*"
whatthepatch = "*"
Expand Down
Loading