diff --git a/cypress/components/DropdownMenu.cy.tsx b/cypress/components/DropdownMenu.cy.tsx index d84a90aea..b98b38a18 100644 --- a/cypress/components/DropdownMenu.cy.tsx +++ b/cypress/components/DropdownMenu.cy.tsx @@ -98,4 +98,67 @@ describe('DropdownMenu Component', () => { cy.get('button').click(); cy.get('[data-testid="test-content"]').should('be.visible'); }); + + it('persists state to localStorage when id is provided', () => { + const testId = 'test-dropdown-id'; + + // Clear storage before test + window.localStorage.clear(); + + // Spy on localStorage + cy.spy(window.localStorage, 'setItem').as('setItem'); + cy.spy(window.localStorage, 'getItem').as('getItem'); + + // 1. Mount and open + cy.mount( + + {mockChildren} + , + ); + + // Initially closed + cy.get('[data-testid="test-content"]').should('not.exist'); + + // Open it + cy.get('button').click(); + cy.get('[data-testid="test-content"]').should('be.visible'); + + // Verify setItem was called + cy.get('@setItem').should( + 'have.been.calledWith', + `sidebar_open_${testId}`, + 'true', + ); + + // 2. Remount (simulate page reload) + cy.mount( + + {mockChildren} + , + ); + + // Verify getItem was called + cy.get('@getItem').should('have.been.calledWith', `sidebar_open_${testId}`); + + // Should be open immediately because of localStorage + cy.get('[data-testid="test-content"]').should('be.visible'); + + // 3. Close it + cy.get('button').click(); + cy.get('@setItem').should( + 'have.been.calledWith', + `sidebar_open_${testId}`, + 'false', + ); + }); }); diff --git a/pages/tools/components/Sidebar.tsx b/pages/tools/components/Sidebar.tsx index e6673b813..69d2dd5d9 100644 --- a/pages/tools/components/Sidebar.tsx +++ b/pages/tools/components/Sidebar.tsx @@ -129,6 +129,7 @@ export default function Sidebar({ label={label} icon={} count={checkedValues.length} + id={accessorKey} > {filterCriteria[accessorKey as FilterCriteriaFields] ?.map(String) diff --git a/pages/tools/components/ui/DropdownMenu.tsx b/pages/tools/components/ui/DropdownMenu.tsx index 3b7ba470b..2176136c8 100644 --- a/pages/tools/components/ui/DropdownMenu.tsx +++ b/pages/tools/components/ui/DropdownMenu.tsx @@ -1,12 +1,12 @@ /* eslint-disable linebreak-style */ /* eslint-disable react-hooks/rules-of-hooks */ /* eslint-disable linebreak-style */ -import { useRouter } from 'next/router'; import React, { type ReactElement, type ReactNode, useEffect, useState, + useRef, } from 'react'; import { Collapsible, @@ -20,6 +20,7 @@ interface DropdownMenuProps { icon: ReactElement; count?: number; testMode?: boolean; + id?: string; } export default function DropdownMenu({ @@ -27,14 +28,27 @@ export default function DropdownMenu({ label, icon, count = 0, + id, }: DropdownMenuProps) { const [isDropdownOpen, setIsDropdownOpen] = useState(false); - const router = useRouter(); - + const isFirstRun = useRef(true); useEffect(() => { - setIsDropdownOpen(false); - }, [router]); - + if (id) { + const storedState = localStorage.getItem(`sidebar_open_${id}`); + if (storedState) { + setIsDropdownOpen(storedState === 'true'); + } + } + }, [id]); + useEffect(() => { + if (id) { + if (isFirstRun.current) { + isFirstRun.current = false; + return; + } + localStorage.setItem(`sidebar_open_${id}`, String(isDropdownOpen)); + } + }, [id, isDropdownOpen]); return (