diff --git a/src/frontend/src/pages/FlowPage/components/PageComponent/MemoizedComponents.tsx b/src/frontend/src/pages/FlowPage/components/PageComponent/MemoizedComponents.tsx index 1e3ee03e65..4594ecc78d 100644 --- a/src/frontend/src/pages/FlowPage/components/PageComponent/MemoizedComponents.tsx +++ b/src/frontend/src/pages/FlowPage/components/PageComponent/MemoizedComponents.tsx @@ -1,19 +1,14 @@ import { Background, Panel } from "@xyflow/react"; -import { cloneDeep } from "lodash"; -import { memo, useCallback, useState } from "react"; -import { useTranslation } from "react-i18next"; +import { memo } from "react"; import { useShallow } from "zustand/react/shallow"; import ForwardedIconComponent from "@/components/common/genericIconComponent"; import CanvasControlButton from "@/components/core/canvasControlsComponent/CanvasControlButton"; import CanvasControls from "@/components/core/canvasControlsComponent/CanvasControls"; -import { Button } from "@/components/ui/button"; import { SidebarTrigger, useSidebar } from "@/components/ui/sidebar"; import { ENABLE_NEW_SIDEBAR } from "@/customization/feature-flags"; -import useSaveFlow from "@/hooks/flows/use-save-flow"; import useFlowStore from "@/stores/flowStore"; import { AllNodeType } from "@/types/flow"; import { cn } from "@/utils/utils"; -import { useSearchContext } from "../flowSidebarComponent"; import { NAV_ITEMS } from "../flowSidebarComponent/components/sidebarSegmentedNav"; export const MemoizedBackground = memo(() => ( @@ -29,91 +24,22 @@ interface MemoizedCanvasControlsProps { } export const MemoizedCanvasControls = memo( - ({ - setIsAddingNote, - shadowBoxWidth, - shadowBoxHeight, - selectedNode, - isAgentWorking, - }: MemoizedCanvasControlsProps) => { - const { t } = useTranslation(); + ({ selectedNode, isAgentWorking }: MemoizedCanvasControlsProps) => { const currentFlow = useFlowStore(useShallow((state) => state.currentFlow)); - const setCurrentFlow = useFlowStore((state) => state.setCurrentFlow); - const saveFlow = useSaveFlow(); const isLocked = currentFlow?.locked ?? false; const effectiveLocked = isLocked || isAgentWorking; - const [isSaving, setIsSaving] = useState(false); - - const handleToggleLock = useCallback(async () => { - if (isAgentWorking || isSaving || !currentFlow) return; - const newFlow = cloneDeep(currentFlow); - newFlow.locked = !isLocked; - setIsSaving(true); - try { - await saveFlow(newFlow); - setCurrentFlow(newFlow); - } finally { - setIsSaving(false); - } - }, [ - currentFlow, - isLocked, - isAgentWorking, - isSaving, - saveFlow, - setCurrentFlow, - ]); return ( - - + /> ); }, ); export const MemoizedSidebarTrigger = memo(() => { const { open, toggleSidebar, setActiveSection } = useSidebar(); - const { focusSearch, isSearchFocused } = useSearchContext(); if (ENABLE_NEW_SIDEBAR) { return ( { if (!open) { toggleSidebar(); } - if (item.id === "search") { - // Add a small delay to ensure the sidebar is open and input is rendered - setTimeout(() => focusSearch(), 100); - } }} testId={item.id} /> diff --git a/src/frontend/src/pages/FlowPage/components/PageComponent/__tests__/MemoizedCanvasControls.test.tsx b/src/frontend/src/pages/FlowPage/components/PageComponent/__tests__/MemoizedCanvasControls.test.tsx index 6f30637817..e23acd8cd8 100644 --- a/src/frontend/src/pages/FlowPage/components/PageComponent/__tests__/MemoizedCanvasControls.test.tsx +++ b/src/frontend/src/pages/FlowPage/components/PageComponent/__tests__/MemoizedCanvasControls.test.tsx @@ -1,9 +1,4 @@ -import { fireEvent, render, screen, waitFor } from "@testing-library/react"; - -const mockSaveFlow: jest.Mock, unknown[]> = jest.fn(() => - Promise.resolve(), -); -const mockSetCurrentFlow = jest.fn(); +import { render, screen } from "@testing-library/react"; const mockCurrentFlow = { id: "test-flow-id", @@ -15,13 +10,6 @@ jest.mock("nanoid", () => ({ nanoid: () => "test-id", })); -jest.mock("../../flowSidebarComponent", () => ({ - useSearchContext: () => ({ - focusSearch: jest.fn(), - isSearchFocused: false, - }), -})); - jest.mock("../../flowSidebarComponent/components/sidebarSegmentedNav", () => ({ NAV_ITEMS: [], })); @@ -49,17 +37,12 @@ jest.mock("@/stores/flowStore", () => ({ default: jest.fn((selector) => { const state = { currentFlow: mockCurrentFlow, - setCurrentFlow: mockSetCurrentFlow, + setCurrentFlow: jest.fn(), }; return selector(state); }), })); -jest.mock("@/hooks/flows/use-save-flow", () => ({ - __esModule: true, - default: () => mockSaveFlow, -})); - jest.mock("@/components/core/canvasControlsComponent/CanvasControls", () => ({ __esModule: true, default: ({ children }) => ( @@ -84,14 +67,6 @@ jest.mock("@/components/common/genericIconComponent", () => ({ ), })); -jest.mock("@/components/ui/button", () => ({ - Button: ({ children, onClick, title, className, ...rest }) => ( - - ), -})); - jest.mock("@/utils/utils", () => ({ cn: (...args: string[]) => args.filter(Boolean).join(" "), })); @@ -112,91 +87,24 @@ describe("MemoizedCanvasControls", () => { mockCurrentFlow.locked = false; }); - it("should_render_unlock_icon_when_flow_is_not_locked", () => { - render(); - - expect(screen.getByTestId("icon-Unlock")).toBeInTheDocument(); - expect(screen.queryByTestId("icon-Lock")).not.toBeInTheDocument(); - }); - - it("should_render_lock_icon_when_flow_is_locked", () => { - mockCurrentFlow.locked = true; - - render(); - - expect(screen.getByTestId("icon-Lock")).toBeInTheDocument(); - expect(screen.queryByTestId("icon-Unlock")).not.toBeInTheDocument(); - }); - - it("should_show_unlock_flow_title_when_flow_is_locked", () => { - mockCurrentFlow.locked = true; - - render(); - - expect(screen.getByTitle("Unlock flow")).toBeInTheDocument(); - }); - - it("should_show_lock_flow_title_when_flow_is_not_locked", () => { - render(); - - expect(screen.getByTitle("Lock flow")).toBeInTheDocument(); - }); - - it("should_call_save_flow_and_set_current_flow_when_lock_button_clicked", async () => { - render(); - - const lockButton = screen.getByTestId("lock-status"); - fireEvent.click(lockButton); - - await waitFor(() => { - expect(mockSaveFlow).toHaveBeenCalledTimes(1); - expect(mockSetCurrentFlow).toHaveBeenCalledTimes(1); - }); - - const savedFlow = (mockSaveFlow.mock.calls as unknown[][])[0]?.[0] as - | Record - | undefined; - expect(savedFlow?.locked).toBe(true); - }); - - it("should_toggle_lock_state_from_locked_to_unlocked", async () => { - mockCurrentFlow.locked = true; - - render(); - - const lockButton = screen.getByTestId("lock-status"); - fireEvent.click(lockButton); - - await waitFor(() => { - expect(mockSaveFlow).toHaveBeenCalledTimes(1); - }); - - const savedFlow = (mockSaveFlow.mock.calls as unknown[][])[0]?.[0] as - | Record - | undefined; - expect(savedFlow?.locked).toBe(false); - }); - - it("should_apply_destructive_color_class_when_flow_is_locked", () => { - mockCurrentFlow.locked = true; - - render(); - - const icon = screen.getByTestId("icon-Lock"); - expect(icon.className).toContain("text-destructive"); - }); - - it("should_not_apply_destructive_color_class_when_flow_is_unlocked", () => { - render(); - - const icon = screen.getByTestId("icon-Unlock"); - expect(icon.className).not.toContain("text-destructive"); - }); - - it("should_render_inside_canvas_controls_wrapper", () => { + it("should_render_canvas_controls_wrapper", () => { render(); expect(screen.getByTestId("canvas-controls")).toBeInTheDocument(); - expect(screen.getByTestId("lock-status")).toBeInTheDocument(); + }); + + it("should_not_render_lock_icon", () => { + render(); + + expect(screen.queryByTestId("icon-Lock")).not.toBeInTheDocument(); + expect(screen.queryByTestId("icon-Unlock")).not.toBeInTheDocument(); + }); + + it("should_not_render_lock_icon_when_flow_is_locked", () => { + mockCurrentFlow.locked = true; + + render(); + + expect(screen.queryByTestId("icon-Lock")).not.toBeInTheDocument(); }); }); diff --git a/src/frontend/tests/core/features/flow-lock.spec.ts b/src/frontend/tests/core/features/flow-lock.spec.ts index 00a4169828..3f4ffb3723 100644 --- a/src/frontend/tests/core/features/flow-lock.spec.ts +++ b/src/frontend/tests/core/features/flow-lock.spec.ts @@ -16,10 +16,6 @@ test.describe("Flow Lock Feature", () => { timeout: 5000, }); - // Verify initially the flow is not locked (no lock icon should be visible) - const initialLockIcon = page.getByTestId("icon-Lock"); - await expect(initialLockIcon).toHaveCount(0); - // Open flow settings by clicking on the flow name await page.getByTestId("flow_name").click(); @@ -70,10 +66,6 @@ test.describe("Flow Lock Feature", () => { timeout: 10000, }); - // Verify lock icon now appears in the flow header - const lockIconInHeader = page.getByTestId("icon-Lock"); - await expect(lockIconInHeader).toBeVisible(); - // Try to open settings again to unlock await page.getByTestId("flow_name").click(); diff --git a/src/frontend/tests/extended/features/lock-flow.spec.ts b/src/frontend/tests/extended/features/lock-flow.spec.ts index 0850104885..ed7e317111 100644 --- a/src/frontend/tests/extended/features/lock-flow.spec.ts +++ b/src/frontend/tests/extended/features/lock-flow.spec.ts @@ -47,10 +47,6 @@ test( //ensure the UI is updated - await page.waitForSelector('[data-testid="icon-Lock"]', { - timeout: 3000, - }); - await unlockFlow(page); await page.getByTestId("icon-ChevronLeft").click();