diff --git a/datahub-web-react/src/app/context/userContext.tsx b/datahub-web-react/src/app/context/userContext.tsx
index c552234648..1ba3a4964a 100644
--- a/datahub-web-react/src/app/context/userContext.tsx
+++ b/datahub-web-react/src/app/context/userContext.tsx
@@ -8,6 +8,7 @@ export type LocalState = {
selectedViewUrn?: string | null;
selectedPath?: string | null;
selectedSearch?: string | null;
+ showBrowseV2Sidebar?: boolean | null;
};
/**
diff --git a/datahub-web-react/src/app/search/SearchResults.tsx b/datahub-web-react/src/app/search/SearchResults.tsx
index 29d81d2bcc..8a0e31e1fb 100644
--- a/datahub-web-react/src/app/search/SearchResults.tsx
+++ b/datahub-web-react/src/app/search/SearchResults.tsx
@@ -23,10 +23,8 @@ import BrowseSidebar from './sidebar';
import ToggleSidebarButton from './ToggleSidebarButton';
import { SidebarProvider } from './sidebar/SidebarContext';
import { BrowseProvider } from './sidebar/BrowseContext';
-import analytics from '../analytics/analytics';
-import useToggle from '../shared/useToggle';
-import { EventType } from '../analytics';
import { useIsBrowseV2, useIsSearchV2 } from './useSearchAndBrowseVersion';
+import useToggleSidebar from './useToggleSidebar';
const SearchResultsWrapper = styled.div<{ showUpdatedStyles: boolean }>`
display: flex;
@@ -151,6 +149,7 @@ export const SearchResults = ({
}: Props) => {
const showSearchFiltersV2 = useIsSearchV2();
const showBrowseV2 = useIsBrowseV2();
+ const { isSidebarOpen, toggleSidebar } = useToggleSidebar();
const pageStart = searchResponse?.start || 0;
const pageSize = searchResponse?.count || 0;
const totalResults = searchResponse?.total || 0;
@@ -161,15 +160,6 @@ export const SearchResults = ({
const searchResultUrns = combinedSiblingSearchResults.map((result) => result.entity.urn) || [];
const selectedEntityUrns = selectedEntities.map((entity) => entity.urn);
- const { isOpen: isSidebarOpen, toggle: toggleSidebar } = useToggle({
- initialValue: true,
- onToggle: (isNowOpen: boolean) =>
- analytics.event({
- type: EventType.BrowseV2ToggleSidebarEvent,
- action: isNowOpen ? 'open' : 'close',
- }),
- });
-
return (
<>
{loading && }
diff --git a/datahub-web-react/src/app/search/ToggleSidebarButton.tsx b/datahub-web-react/src/app/search/ToggleSidebarButton.tsx
index bdfc1e77d7..0f5d00fcd7 100644
--- a/datahub-web-react/src/app/search/ToggleSidebarButton.tsx
+++ b/datahub-web-react/src/app/search/ToggleSidebarButton.tsx
@@ -1,6 +1,6 @@
-import React, { memo } from 'react';
+import React, { memo, useState } from 'react';
import Icon from '@ant-design/icons/lib/components/Icon';
-import { Button } from 'antd';
+import { Button, Tooltip } from 'antd';
import styled from 'styled-components';
import { ReactComponent as ExpandIcon } from '../../images/expand.svg';
import { ReactComponent as CollapseIcon } from '../../images/collapse.svg';
@@ -12,9 +12,37 @@ const ToggleIcon = styled(Icon)`
}
`;
-const ToggleSidebarButton = ({ isOpen, onClick }: { isOpen: boolean; onClick: () => void }) => {
+type Props = {
+ isOpen: boolean;
+ onClick: () => void;
+};
+
+const ToggleSidebarButton = ({ isOpen, onClick }: Props) => {
+ const [pauseTooltip, setPauseTooltip] = useState(false);
+ const title = isOpen ? 'Hide the navigation panel' : 'Open the navigation panel';
+ const placement = isOpen ? 'bottom' : 'bottomRight';
+
+ const onClickButton = () => {
+ setPauseTooltip(true);
+ window.setTimeout(() => setPauseTooltip(false), 250);
+ onClick();
+ };
+
+ const button = (
+ }
+ />
+ );
+
+ if (pauseTooltip) return button;
+
return (
- } />
+
+ {button}
+
);
};
diff --git a/datahub-web-react/src/app/search/useToggleSidebar.ts b/datahub-web-react/src/app/search/useToggleSidebar.ts
new file mode 100644
index 0000000000..dfe3f68f6c
--- /dev/null
+++ b/datahub-web-react/src/app/search/useToggleSidebar.ts
@@ -0,0 +1,23 @@
+import { EventType } from '../analytics';
+import analytics from '../analytics/analytics';
+import { useUserContext } from '../context/useUserContext';
+import useToggle from '../shared/useToggle';
+
+const useToggleSidebar = () => {
+ const { localState, updateLocalState } = useUserContext();
+
+ const { isOpen: isSidebarOpen, toggle: toggleSidebar } = useToggle({
+ initialValue: localState.showBrowseV2Sidebar ?? true,
+ onToggle: (isNowOpen: boolean) => {
+ analytics.event({
+ type: EventType.BrowseV2ToggleSidebarEvent,
+ action: isNowOpen ? 'open' : 'close',
+ });
+ updateLocalState({ ...localState, showBrowseV2Sidebar: isNowOpen });
+ },
+ });
+
+ return { isSidebarOpen, toggleSidebar } as const;
+};
+
+export default useToggleSidebar;
diff --git a/datahub-web-react/src/app/shared/useToggle.ts b/datahub-web-react/src/app/shared/useToggle.ts
index 802f8611d9..b020bf030f 100644
--- a/datahub-web-react/src/app/shared/useToggle.ts
+++ b/datahub-web-react/src/app/shared/useToggle.ts
@@ -2,25 +2,32 @@ import { useState } from 'react';
const NOOP = (_: boolean) => {};
-const useToggle = ({ initialValue = false, closeDelay = 0, onToggle = NOOP } = {}) => {
+const useToggle = ({ initialValue = false, closeDelay = 0, openDelay = 0, onToggle = NOOP } = {}) => {
const [isOpen, setIsOpen] = useState(initialValue);
- const [isClosing, setIsClosing] = useState(false);
+ const [transition, setTransition] = useState<'opening' | 'closing' | null>(null);
+ const isOpening = transition === 'opening';
+ const isClosing = transition === 'closing';
+ const isTransitioning = transition !== null;
const toggle = () => {
if (isOpen) {
- setIsClosing(true);
+ setTransition('closing');
window.setTimeout(() => {
setIsOpen(false);
+ setTransition(null);
onToggle(false);
}, closeDelay);
} else {
- setIsClosing(false);
- setIsOpen(true);
- onToggle(true);
+ setTransition('opening');
+ window.setTimeout(() => {
+ setIsOpen(true);
+ setTransition(null);
+ onToggle(true);
+ }, openDelay);
}
};
- return { isOpen, isClosing, toggle } as const;
+ return { isOpen, isClosing, isOpening, isTransitioning, toggle } as const;
};
export default useToggle;
diff --git a/smoke-test/tests/cypress/cypress/e2e/browse/browseV2.js b/smoke-test/tests/cypress/cypress/e2e/browse/browseV2.js
index 5f63ca7f24..144531dcf2 100644
--- a/smoke-test/tests/cypress/cypress/e2e/browse/browseV2.js
+++ b/smoke-test/tests/cypress/cypress/e2e/browse/browseV2.js
@@ -36,6 +36,41 @@ describe("search", () => {
cy.get("[data-testid=browse-v2").should("not.exist");
});
+ it("should hide and show the sidebar when the toggle button is clicked", () => {
+ setBrowseFeatureFlag(true);
+ cy.login();
+ cy.visit("/");
+ cy.get("input[data-testid=search-input]").type("*{enter}");
+
+ cy.get("[data-testid=browse-v2")
+ .invoke("css", "width")
+ .should("match", /^\d\d\dpx$/);
+
+ cy.get("[data-testid=browse-v2-toggle").click();
+
+ cy.get("[data-testid=browse-v2")
+ .invoke("css", "width")
+ .should("match", /^\dpx$/);
+
+ cy.reload();
+
+ cy.get("[data-testid=browse-v2")
+ .invoke("css", "width")
+ .should("match", /^\dpx$/);
+
+ cy.get("[data-testid=browse-v2-toggle").click();
+
+ cy.get("[data-testid=browse-v2")
+ .invoke("css", "width")
+ .should("match", /^\d\d\dpx$/);
+
+ cy.reload();
+
+ cy.get("[data-testid=browse-v2")
+ .invoke("css", "width")
+ .should("match", /^\d\d\dpx$/);
+ });
+
it("should take you to the old browse experience when clicking entity type on home page with the browse flag off", () => {
setBrowseFeatureFlag(false);
cy.login();