mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[Security Solution] Exp flyout expandable widget rendering (#160625)
## Summary This tiny PR ensures that widget contents are not rendered until expanded (in the expandable flyout). This will prevent unnecessary requests being sent when we open the flyout. Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
bc4ffb6634
commit
901b9eb127
4 changed files with 67 additions and 13 deletions
|
@ -27,6 +27,12 @@ export interface ExpandableFlyoutProps extends EuiFlyoutProps {
|
|||
handleOnFlyoutClosed?: () => void;
|
||||
}
|
||||
|
||||
const flyoutStyles = css`
|
||||
overflow-y: scroll;
|
||||
`;
|
||||
|
||||
const flyoutInnerStyles = { height: '100%' };
|
||||
|
||||
/**
|
||||
* Expandable flyout UI React component.
|
||||
* Displays 3 sections (right, left, preview) depending on the panels in the context.
|
||||
|
@ -65,9 +71,10 @@ export const ExpandableFlyout: React.FC<ExpandableFlyoutProps> = ({
|
|||
[mostRecentPreview, registeredPanels]
|
||||
);
|
||||
|
||||
// do not add the flyout to the dom if there aren't any panels to display
|
||||
if (!left && !right && !preview.length) {
|
||||
return <></>;
|
||||
const hideFlyout = !left && !right && !preview.length;
|
||||
|
||||
if (hideFlyout) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const flyoutWidth: string = leftSection && rightSection ? 'l' : 's';
|
||||
|
@ -77,9 +84,7 @@ export const ExpandableFlyout: React.FC<ExpandableFlyoutProps> = ({
|
|||
|
||||
return (
|
||||
<EuiFlyout
|
||||
css={css`
|
||||
overflow-y: scroll;
|
||||
`}
|
||||
css={flyoutStyles}
|
||||
{...flyoutProps}
|
||||
size={flyoutWidth}
|
||||
ownFocus={false}
|
||||
|
@ -89,7 +94,7 @@ export const ExpandableFlyout: React.FC<ExpandableFlyoutProps> = ({
|
|||
direction={leftSection ? 'row' : 'column'}
|
||||
wrap={false}
|
||||
gutterSize="none"
|
||||
style={{ height: '100%' }}
|
||||
style={flyoutInnerStyles}
|
||||
>
|
||||
{leftSection && left ? (
|
||||
<LeftSection
|
||||
|
|
|
@ -46,6 +46,7 @@ describe(
|
|||
waitForAlertsToPopulate();
|
||||
expandFirstAlertExpandableFlyout();
|
||||
expandDocumentDetailsExpandableFlyoutLeftSection();
|
||||
createNewCaseFromExpandableFlyout();
|
||||
openInsightsTab();
|
||||
openCorrelationsTab();
|
||||
});
|
||||
|
@ -53,8 +54,6 @@ describe(
|
|||
it('should render correlations details correctly', () => {
|
||||
cy.log('link the alert to a new case');
|
||||
|
||||
createNewCaseFromExpandableFlyout();
|
||||
|
||||
cy.get(DOCUMENT_DETAILS_FLYOUT_INSIGHTS_TAB).scrollIntoView();
|
||||
|
||||
cy.log('should render the Insights header');
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
*/
|
||||
|
||||
import { EuiAccordion, EuiFlexGroup, EuiSpacer, EuiTitle, useGeneratedHtmlId } from '@elastic/eui';
|
||||
import type { VFC } from 'react';
|
||||
import React from 'react';
|
||||
import React, { type VFC } from 'react';
|
||||
import { useAccordionState } from '../hooks/use_accordion_state';
|
||||
|
||||
export const HEADER_TEST_ID = 'Header';
|
||||
export const CONTENT_TEST_ID = 'Content';
|
||||
|
@ -46,6 +46,8 @@ export const ExpandableSection: VFC<DescriptionSectionProps> = ({
|
|||
}) => {
|
||||
const accordionId = useGeneratedHtmlId({ prefix: 'accordion' });
|
||||
|
||||
const { renderContent, toggle, state } = useAccordionState(expanded);
|
||||
|
||||
const headerDataTestSub = dataTestSub + HEADER_TEST_ID;
|
||||
const contentDataTestSub = dataTestSub + CONTENT_TEST_ID;
|
||||
|
||||
|
@ -56,10 +58,10 @@ export const ExpandableSection: VFC<DescriptionSectionProps> = ({
|
|||
);
|
||||
|
||||
return (
|
||||
<EuiAccordion id={accordionId} buttonContent={header} initialIsOpen={expanded}>
|
||||
<EuiAccordion forceState={state} onToggle={toggle} id={accordionId} buttonContent={header}>
|
||||
<EuiSpacer size="m" />
|
||||
<EuiFlexGroup gutterSize="none" direction="column" data-test-subj={contentDataTestSub}>
|
||||
{children}
|
||||
{renderContent && children}
|
||||
</EuiFlexGroup>
|
||||
</EuiAccordion>
|
||||
);
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { useReducer } from 'react';
|
||||
|
||||
const CLOSED = 'closed' as const;
|
||||
const OPEN = 'open' as const;
|
||||
|
||||
type ToggleReducerState = typeof CLOSED | typeof OPEN;
|
||||
const toggleReducer = (state: ToggleReducerState) => {
|
||||
return state === CLOSED ? OPEN : CLOSED;
|
||||
};
|
||||
|
||||
export interface UseAccordionStateValue {
|
||||
/**
|
||||
* Should children be rendered in the dom
|
||||
*/
|
||||
renderContent: boolean;
|
||||
/**
|
||||
* Use this to control the accordion visual state
|
||||
*/
|
||||
state: typeof CLOSED | typeof OPEN;
|
||||
|
||||
/**
|
||||
* Handler function for cycling between the states
|
||||
*/
|
||||
toggle: VoidFunction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tiny hook for controlled useAccordionState
|
||||
* @param expandedInitially - is accordion expanded on first render
|
||||
*/
|
||||
export const useAccordionState = (expandedInitially: boolean): UseAccordionStateValue => {
|
||||
const initialState = expandedInitially ? OPEN : CLOSED;
|
||||
const [state, toggle] = useReducer(toggleReducer, initialState);
|
||||
const renderContent = state === OPEN;
|
||||
|
||||
return {
|
||||
renderContent,
|
||||
state,
|
||||
toggle,
|
||||
};
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue