[Security Solution] expanded flyout using dynamic width (#154114)

This commit is contained in:
Philippe Oberti 2023-04-05 22:45:09 -05:00 committed by GitHub
parent ac621ab49c
commit fef2cbd0db
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 29 additions and 41 deletions

View file

@ -61,6 +61,5 @@ A set of properties defining what's displayed in one of the flyout section.
## Future work ## Future work
- currently the panels are aware of their width. This should be changed and the width of the left, right and preview sections should be handled by the flyout itself - add the feature to save the flyout state (layout) to the url (https://github.com/elastic/security-team/issues/6119)
- add the feature to save the flyout state (layout) to the url
- introduce the notion of scope to be able to handle more than one flyout per plugin?? - introduce the notion of scope to be able to handle more than one flyout per plugin??

View file

@ -26,10 +26,8 @@ interface LeftSectionProps {
*/ */
export const LeftSection: React.FC<LeftSectionProps> = ({ component, width }: LeftSectionProps) => { export const LeftSection: React.FC<LeftSectionProps> = ({ component, width }: LeftSectionProps) => {
return ( return (
<EuiFlexItem grow data-test-subj={LEFT_SECTION}> <EuiFlexItem grow data-test-subj={LEFT_SECTION} style={{ width: `${width * 100}%` }}>
<EuiFlexGroup direction="column" style={{ maxWidth: width, width: 'auto' }}> <EuiFlexGroup direction="column">{component}</EuiFlexGroup>
{component}
</EuiFlexGroup>
</EuiFlexItem> </EuiFlexItem>
); );
}; };

View file

@ -32,7 +32,7 @@ interface PreviewSectionProps {
/** /**
* Width used when rendering the panel * Width used when rendering the panel
*/ */
width: number | undefined; width: number;
/** /**
* Display the back button in the header * Display the back button in the header
*/ */
@ -50,8 +50,7 @@ export const PreviewSection: React.FC<PreviewSectionProps> = ({
}: PreviewSectionProps) => { }: PreviewSectionProps) => {
const { euiTheme } = useEuiTheme(); const { euiTheme } = useEuiTheme();
const { closePreviewPanel, previousPreviewPanel } = useExpandableFlyoutContext(); const { closePreviewPanel, previousPreviewPanel } = useExpandableFlyoutContext();
const left = `${(1 - width) * 100}%`;
const previewWith: string = width ? `${width}px` : '0px';
const closeButton = ( const closeButton = (
<EuiFlexItem grow={false}> <EuiFlexItem grow={false}>
@ -91,7 +90,7 @@ export const PreviewSection: React.FC<PreviewSectionProps> = ({
top: 0; top: 0;
bottom: 0; bottom: 0;
right: 0; right: 0;
left: ${previewWith}; left: ${left};
background-color: ${euiTheme.colors.shadow}; background-color: ${euiTheme.colors.shadow};
opacity: 0.5; opacity: 0.5;
`} `}
@ -102,7 +101,7 @@ export const PreviewSection: React.FC<PreviewSectionProps> = ({
top: 0; top: 0;
bottom: 0; bottom: 0;
right: 0; right: 0;
left: ${previewWith}; left: ${left};
z-index: 1000; z-index: 1000;
`} `}
> >

View file

@ -29,10 +29,12 @@ export const RightSection: React.FC<RightSectionProps> = ({
width, width,
}: RightSectionProps) => { }: RightSectionProps) => {
return ( return (
<EuiFlexItem grow={false} style={{ height: '100%' }} data-test-subj={RIGHT_SECTION}> <EuiFlexItem
<EuiFlexGroup direction="column" style={{ width }}> grow={false}
{component} style={{ height: '100%', width: `${width * 100}%` }}
</EuiFlexGroup> data-test-subj={RIGHT_SECTION}
>
<EuiFlexGroup direction="column">{component}</EuiFlexGroup>
</EuiFlexItem> </EuiFlexItem>
); );
}; };

View file

@ -17,7 +17,6 @@ describe('ExpandableFlyout', () => {
const registeredPanels: Panel[] = [ const registeredPanels: Panel[] = [
{ {
key: 'key', key: 'key',
width: 500,
component: () => <div>{'component'}</div>, component: () => <div>{'component'}</div>,
}, },
]; ];

View file

@ -30,6 +30,9 @@ export interface ExpandableFlyoutProps extends EuiFlyoutProps {
/** /**
* Expandable flyout UI React component. * Expandable flyout UI React component.
* Displays 3 sections (right, left, preview) depending on the panels in the context. * Displays 3 sections (right, left, preview) depending on the panels in the context.
*
* The behavior expects that the left and preview sections should only be displayed is a right section
* is already rendered.
*/ */
export const ExpandableFlyout: React.FC<ExpandableFlyoutProps> = ({ export const ExpandableFlyout: React.FC<ExpandableFlyoutProps> = ({
registeredPanels, registeredPanels,
@ -67,7 +70,10 @@ export const ExpandableFlyout: React.FC<ExpandableFlyoutProps> = ({
return <></>; return <></>;
} }
const width: number = (leftSection?.width ?? 0) + (rightSection?.width ?? 0); const flyoutWidth: string = leftSection && rightSection ? 'l' : 's';
const rightSectionWidth: number = leftSection ? 0.4 : 1;
const leftSectionWidth: number = 0.6;
const previewSectionWidth: number = leftSection ? 0.4 : 1;
return ( return (
<EuiFlyout <EuiFlyout
@ -75,7 +81,7 @@ export const ExpandableFlyout: React.FC<ExpandableFlyoutProps> = ({
overflow-y: scroll; overflow-y: scroll;
`} `}
{...flyoutProps} {...flyoutProps}
size={width} size={flyoutWidth}
ownFocus={false} ownFocus={false}
onClose={onClose} onClose={onClose}
> >
@ -88,13 +94,13 @@ export const ExpandableFlyout: React.FC<ExpandableFlyoutProps> = ({
{leftSection && left ? ( {leftSection && left ? (
<LeftSection <LeftSection
component={leftSection.component({ ...(left as FlyoutPanel) })} component={leftSection.component({ ...(left as FlyoutPanel) })}
width={leftSection.width} width={leftSectionWidth}
/> />
) : null} ) : null}
{rightSection && right ? ( {rightSection && right ? (
<RightSection <RightSection
component={rightSection.component({ ...(right as FlyoutPanel) })} component={rightSection.component({ ...(right as FlyoutPanel) })}
width={rightSection.width} width={rightSectionWidth}
/> />
) : null} ) : null}
</EuiFlexGroup> </EuiFlexGroup>
@ -103,7 +109,7 @@ export const ExpandableFlyout: React.FC<ExpandableFlyoutProps> = ({
<PreviewSection <PreviewSection
component={previewSection.component({ ...(mostRecentPreview as FlyoutPanel) })} component={previewSection.component({ ...(mostRecentPreview as FlyoutPanel) })}
showBackButton={showBackButton} showBackButton={showBackButton}
width={leftSection?.width} width={previewSectionWidth}
/> />
) : null} ) : null}
</EuiFlyout> </EuiFlyout>

View file

@ -36,8 +36,4 @@ export interface Panel {
* Component to be rendered * Component to be rendered
*/ */
component: (props: FlyoutPanel) => React.ReactElement; component: (props: FlyoutPanel) => React.ReactElement;
/**
* Width used when rendering the panel
*/
width: number; // TODO remove this, see https://github.com/elastic/security-team/issues/6247
} }

View file

@ -14,11 +14,6 @@ import type { LeftPanelProps } from './left';
import { LeftPanel, LeftPanelKey } from './left'; import { LeftPanel, LeftPanelKey } from './left';
import { LeftPanelProvider } from './left/context'; import { LeftPanelProvider } from './left/context';
// TODO these should be replaced by a more dynamic solution
// see https://github.com/elastic/security-team/issues/6247
export const RIGHT_SECTION_WIDTH = 500;
export const LEFT_SECTION_WIDTH = 1000;
/** /**
* List of all panels that will be used within the document details expandable flyout. * List of all panels that will be used within the document details expandable flyout.
* This needs to be passed to the expandable flyout registeredPanels property. * This needs to be passed to the expandable flyout registeredPanels property.
@ -26,7 +21,6 @@ export const LEFT_SECTION_WIDTH = 1000;
export const expandableFlyoutDocumentsPanels: ExpandableFlyoutProps['registeredPanels'] = [ export const expandableFlyoutDocumentsPanels: ExpandableFlyoutProps['registeredPanels'] = [
{ {
key: RightPanelKey, key: RightPanelKey,
width: RIGHT_SECTION_WIDTH,
component: (props) => ( component: (props) => (
<RightPanelProvider {...(props as RightPanelProps).params}> <RightPanelProvider {...(props as RightPanelProps).params}>
<RightPanel path={props.path as RightPanelProps['path']} /> <RightPanel path={props.path as RightPanelProps['path']} />
@ -35,7 +29,6 @@ export const expandableFlyoutDocumentsPanels: ExpandableFlyoutProps['registeredP
}, },
{ {
key: LeftPanelKey, key: LeftPanelKey,
width: LEFT_SECTION_WIDTH,
component: (props) => ( component: (props) => (
<LeftPanelProvider {...(props as LeftPanelProps).params}> <LeftPanelProvider {...(props as LeftPanelProps).params}>
<LeftPanel path={props.path as LeftPanelProps['path']} /> <LeftPanel path={props.path as LeftPanelProps['path']} />

View file

@ -8,13 +8,9 @@
import React from 'react'; import React from 'react';
import { css } from '@emotion/react'; import { css } from '@emotion/react';
import type { Story } from '@storybook/react'; import type { Story } from '@storybook/react';
import { RIGHT_SECTION_WIDTH } from '../..';
import { Description } from './description'; import { Description } from './description';
import { RightPanelContext } from '../context'; import { RightPanelContext } from '../context';
const PADDING = 24;
const WIDTH = RIGHT_SECTION_WIDTH - 2 * PADDING;
const ruleUuid = { const ruleUuid = {
category: 'kibana', category: 'kibana',
field: 'kibana.alert.rule.uuid', field: 'kibana.alert.rule.uuid',
@ -46,7 +42,7 @@ export const RuleExpand: Story<void> = () => {
<RightPanelContext.Provider value={panelContextValue}> <RightPanelContext.Provider value={panelContextValue}>
<div <div
css={css` css={css`
width: ${WIDTH}px; // this mimics the current 500 width of the right panel width: 500px;
`} `}
> >
<Description /> <Description />
@ -64,7 +60,7 @@ export const RuleCollapse: Story<void> = () => {
<RightPanelContext.Provider value={panelContextValue}> <RightPanelContext.Provider value={panelContextValue}>
<div <div
css={css` css={css`
width: ${WIDTH}px; // this mimics the current 500 width of the right panel width: 500px;
`} `}
> >
<Description expanded={true} /> <Description expanded={true} />
@ -90,7 +86,7 @@ export const Document: Story<void> = () => {
<RightPanelContext.Provider value={panelContextValue}> <RightPanelContext.Provider value={panelContextValue}>
<div <div
css={css` css={css`
width: ${WIDTH}px; // this mimics the current 500 width of the right panel width: 500px;
`} `}
> >
<Description /> <Description />
@ -116,7 +112,7 @@ export const EmptyDescription: Story<void> = () => {
<RightPanelContext.Provider value={panelContextValue}> <RightPanelContext.Provider value={panelContextValue}>
<div <div
css={css` css={css`
width: ${WIDTH}px; // this mimics the current 500 width of the right panel width: 500px;
`} `}
> >
<Description expanded={true} /> <Description expanded={true} />
@ -131,7 +127,7 @@ export const Empty: Story<void> = () => {
<RightPanelContext.Provider value={panelContextValue}> <RightPanelContext.Provider value={panelContextValue}>
<div <div
css={css` css={css`
width: ${WIDTH}px; // this mimics the current 500 width of the right panel width: 500px;
`} `}
> >
<Description expanded={true} /> <Description expanded={true} />