Procházet zdrojové kódy

Fix issue #5605: [Bug]: UI regression, Jupyter tab has no vertical scroll bar, cannot see all actions (#5607)

OpenHands před 1 rokem
rodič
revize
fdc00fbca0

+ 45 - 0
frontend/__tests__/components/jupyter/jupyter.test.tsx

@@ -0,0 +1,45 @@
+import { render, screen } from "@testing-library/react";
+import { Provider } from "react-redux";
+import { configureStore } from "@reduxjs/toolkit";
+import { JupyterEditor } from "#/components/features/jupyter/jupyter";
+import { jupyterReducer } from "#/state/jupyter-slice";
+import { vi, describe, it, expect } from "vitest";
+
+describe("JupyterEditor", () => {
+  const mockStore = configureStore({
+    reducer: {
+      fileState: () => ({}),
+      initalQuery: () => ({}),
+      browser: () => ({}),
+      chat: () => ({}),
+      code: () => ({}),
+      cmd: () => ({}),
+      agent: () => ({}),
+      jupyter: jupyterReducer,
+      securityAnalyzer: () => ({}),
+      status: () => ({}),
+    },
+    preloadedState: {
+      jupyter: {
+        cells: Array(20).fill({
+          content: "Test cell content",
+          type: "input",
+          output: "Test output",
+        }),
+      },
+    },
+  });
+
+  it("should have a scrollable container", () => {
+    render(
+      <Provider store={mockStore}>
+        <div style={{ height: "100vh" }}>
+          <JupyterEditor maxWidth={800} />
+        </div>
+      </Provider>
+    );
+
+    const container = screen.getByTestId("jupyter-container");
+    expect(container).toHaveClass("flex-1 overflow-y-auto");
+  });
+});

+ 4 - 3
frontend/src/components/features/jupyter/jupyter.tsx

@@ -10,16 +10,17 @@ interface JupyterEditorProps {
 }
 
 export function JupyterEditor({ maxWidth }: JupyterEditorProps) {
-  const { cells } = useSelector((state: RootState) => state.jupyter);
+  const cells = useSelector((state: RootState) => state.jupyter?.cells ?? []);
   const jupyterRef = React.useRef<HTMLDivElement>(null);
 
   const { hitBottom, scrollDomToBottom, onChatBodyScroll } =
     useScrollToBottom(jupyterRef);
 
   return (
-    <div className="flex-1" style={{ maxWidth }}>
+    <div className="flex-1 h-full flex flex-col" style={{ maxWidth }}>
       <div
-        className="overflow-y-auto h-full"
+        data-testid="jupyter-container"
+        className="flex-1 overflow-y-auto"
         ref={jupyterRef}
         onScroll={(e) => onChatBodyScroll(e.currentTarget)}
       >

+ 1 - 1
frontend/src/routes/_oh.app.jupyter.tsx

@@ -14,7 +14,7 @@ function Jupyter() {
   }, []);
 
   return (
-    <div ref={parentRef}>
+    <div ref={parentRef} className="h-full">
       <JupyterEditor maxWidth={parentWidth} />
     </div>
   );

+ 5 - 4
frontend/src/state/jupyter-slice.ts

@@ -7,8 +7,8 @@ export type Cell = {
 
 const initialCells: Cell[] = [];
 
-export const cellSlice = createSlice({
-  name: "cell",
+export const jupyterSlice = createSlice({
+  name: "jupyter",
   initialState: {
     cells: initialCells,
   },
@@ -26,6 +26,7 @@ export const cellSlice = createSlice({
 });
 
 export const { appendJupyterInput, appendJupyterOutput, clearJupyter } =
-  cellSlice.actions;
+  jupyterSlice.actions;
 
-export default cellSlice.reducer;
+export const jupyterReducer = jupyterSlice.reducer;
+export default jupyterReducer;

+ 1 - 1
frontend/src/store.ts

@@ -6,7 +6,7 @@ import codeReducer from "./state/code-slice";
 import fileStateReducer from "./state/file-state-slice";
 import initialQueryReducer from "./state/initial-query-slice";
 import commandReducer from "./state/command-slice";
-import jupyterReducer from "./state/jupyter-slice";
+import { jupyterReducer } from "./state/jupyter-slice";
 import securityAnalyzerReducer from "./state/security-analyzer-slice";
 import statusReducer from "./state/status-slice";