Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
*/
'use client';

import { useMemo, useState } from 'react';
import { HeaderMenuButton, SideNavItems, Search, Button, InlineNotification } from '@carbon/react';
import { useEffect, useMemo, useState } from 'react';
import { HeaderMenuButton, Search, Button, InlineNotification } from '@carbon/react';
import { Add } from '@carbon/icons-react';
import styles from '@/styles/test-runs/saved-queries/CollapsibleSideBar.module.css';
import testRunsPageStyles from '@/styles/test-runs/TestRunsPage.module.css';
import {
arrayMove,
SortableContext,
Expand Down Expand Up @@ -57,6 +58,11 @@ export default function CollapsibleSideBar({ handleEditQueryName }: CollapsibleS
// State to hold the data of the item currently being dragged for the DragOverlay
const [activeQuery, setActiveQuery] = useState<SavedQueryType | null>(null);

const [sideNavExpandedHeight, setSideNavExpandedHeight] = useState(0);
const [mainContentElement, setMainContentElement] = useState<Element | null>(null);
const SIDE_NAV_MIN_HEIGHT_PIXELS = 700;
const SIDE_NAV_HEIGHT_IF_NOT_RESIZABLE_PIXELS = 850;

// Isolate user-sortable queries from the default query
const sortableQueries = useMemo(
() => savedQueries.filter((query) => query.createdAt !== defaultQuery.createdAt),
Expand Down Expand Up @@ -148,6 +154,51 @@ export default function CollapsibleSideBar({ handleEditQueryName }: CollapsibleS
return sortableQueries;
}, [searchTerm, sortableQueries]);

// Grab the main content element on page load.
useEffect(() => {
setMainContentElement(document.querySelector('.' + testRunsPageStyles.mainContent));
}, []);

useEffect(() => {
const updateSideNavHeight = () => {
if (mainContentElement) {
// As the mainContent for the test runs details is also flex, we must set this height to a minimum, wait a short while, then set the height of this element to the main content minus an offset.
setSideNavExpandedHeight(SIDE_NAV_MIN_HEIGHT_PIXELS);
setTimeout(() => {
// The .clientHeight seems to need mainContentElement checked inside the setTimeout().
if (mainContentElement) {
const newHeight = mainContentElement.clientHeight - 50;
setSideNavExpandedHeight(newHeight);
}
}, 0);
}
};

// Initial update
updateSideNavHeight();

// Add event listener for main content resize.
const resizeObserver = new ResizeObserver((entries) => {
// Check if there's a valid entry.
if (entries[0]) {
updateSideNavHeight();
}
});

if (mainContentElement) {
resizeObserver.observe(mainContentElement);
} else {
setSideNavExpandedHeight(SIDE_NAV_HEIGHT_IF_NOT_RESIZABLE_PIXELS);
}

// Cleanup function to remove the event listener when the component unmounts
return () => {
if (mainContentElement) {
resizeObserver.unobserve(mainContentElement);
}
};
}, [mainContentElement]);

return (
<div className={styles.container} aria-label={translations('savedQueriesHeaderLabel')}>
<DndContext
Expand All @@ -167,6 +218,7 @@ export default function CollapsibleSideBar({ handleEditQueryName }: CollapsibleS
<div className={styles.sidebarWrapper}>
<div
className={isExpanded ? styles.sideNavExpanded : styles.sideNavCollapsed}
style={{ height: sideNavExpandedHeight }}
aria-label={translations('savedQueriesSidebarLabel')}
>
<div className={styles.innerContentWrapper}>
Expand Down
1 change: 0 additions & 1 deletion galasa-ui/src/styles/test-runs/TestRunsPage.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -410,4 +410,3 @@
inset: 0;
z-index: 1;
}

Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
max-width: 360px;
background-color: var(--cds-layer);
border-right: 1px solid var(--cds-border-subtle);
height: 800px;
overflow-y: auto;
overflow-x: hidden;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/
import React from 'react';
import '@testing-library/jest-dom';
import { fireEvent, render, screen } from '@testing-library/react';
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import CollapsibleSideBar from '@/components/test-runs/saved-queries/CollapsibleSideBar';
import { useSavedQueries } from '@/contexts/SavedQueriesContext';
import { useTestRunsQueryParams } from '@/contexts/TestRunsQueryParamsContext';
Expand All @@ -22,6 +22,9 @@ const mockQueries = [
{ createdAt: '2023-01-02T00:00:00Z', title: 'Test Run 2', url: '' },
{ createdAt: '2023-01-03T00:00:00Z', title: 'Test Run 3', url: '' },
];
let resizeObserverMock: jest.Mock;
let mockObserve: jest.Mock;
let mockUnobserve: jest.Mock;

// Mock child components
jest.mock('@/components/test-runs/saved-queries/QueryItem', () => ({
Expand Down Expand Up @@ -83,6 +86,19 @@ beforeEach(() => {
defaultQuery: mockQueries[0],
setSavedQueries: mockSetSavedQueries,
}));

resizeObserverMock = jest.fn().mockImplementation(() => {
mockObserve = jest.fn();
mockUnobserve = jest.fn();
const mockDisconnect = jest.fn();

return {
observe: mockObserve,
unobserve: mockUnobserve,
disconnect: mockDisconnect,
};
});
window.ResizeObserver = resizeObserverMock;
});

describe('CollapsibleSideBar', () => {
Expand Down Expand Up @@ -336,4 +352,33 @@ describe('CollapsibleSideBar', () => {
expect(mockSetSavedQueries).not.toHaveBeenCalled();
});
});

describe('updating side nav height', () => {
test('should not observe the main content if main content not loaded', async () => {
render(<CollapsibleSideBar handleEditQueryName={mockHandleEditQueryName} />);
expect(mockObserve).toHaveBeenCalledTimes(0);
});

test('should observe the main content if main content rendered, and set to height of main content -50px', async () => {
const mainContentElement = document.createElement('div');
mainContentElement.className = 'mainContent';
document.body.appendChild(mainContentElement);

render(<CollapsibleSideBar handleEditQueryName={mockHandleEditQueryName} />);

const sidebar = screen.getByLabelText('Saved Queries Sidebar');

await waitFor(() => {
expect(mockObserve).toHaveBeenCalledTimes(1);

if (sidebar) {
expect(sidebar.style.height).toBe('-50px');
} else {
fail('could not find sidebar');
}

document.body.innerHTML = '';
});
});
});
});