Skip to content

Commit

Permalink
Make analyzer work with EuiDataGrid full screen
Browse files Browse the repository at this point in the history
  • Loading branch information
kqualters-elastic committed Sep 1, 2021
1 parent d25108e commit e610891
Show file tree
Hide file tree
Showing 5 changed files with 188 additions and 98 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ export const resetScroll = () => {
}
}, 0);
};

interface GlobalFullScreen {
globalFullScreen: boolean;
setGlobalFullScreen: (fullScreen: boolean) => void;
Expand All @@ -46,10 +45,10 @@ export const useGlobalFullScreen = (): GlobalFullScreen => {
const setGlobalFullScreen = useCallback(
(fullScreen: boolean) => {
if (fullScreen) {
document.body.classList.add(SCROLLING_DISABLED_CLASS_NAME);
document.body.classList.add(SCROLLING_DISABLED_CLASS_NAME, 'euiDataGrid__restrictBody');
resetScroll();
} else {
document.body.classList.remove(SCROLLING_DISABLED_CLASS_NAME);
document.body.classList.remove(SCROLLING_DISABLED_CLASS_NAME, 'euiDataGrid__restrictBody');
resetScroll();
}

Expand All @@ -71,9 +70,15 @@ export const useTimelineFullScreen = (): TimelineFullScreen => {
const dispatch = useDispatch();
const timelineFullScreen =
useShallowEqualSelector(inputsSelectors.timelineFullScreenSelector) ?? false;

const setTimelineFullScreen = useCallback(
(fullScreen: boolean) => dispatch(inputsActions.setFullScreen({ id: 'timeline', fullScreen })),
(fullScreen: boolean) => {
if (fullScreen) {
document.body.classList.add('euiDataGrid__restrictBody');
} else {
document.body.classList.remove('euiDataGrid__restrictBody');
}
dispatch(inputsActions.setFullScreen({ id: 'timeline', fullScreen }));
},
[dispatch]
);
const memoizedReturn = useMemo(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ import {
setActiveTabTimeline,
updateTimelineGraphEventId,
} from '../../../../timelines/store/timeline/actions';
import {
useGlobalFullScreen,
useTimelineFullScreen,
} from '../../../../common/containers/use_full_screen';
import { TimelineId, TimelineTabs } from '../../../../../common';
import { ACTION_INVESTIGATE_IN_RESOLVER } from '../../../../timelines/components/timeline/body/translations';
import { Ecs } from '../../../../../common/ecs';
Expand All @@ -35,13 +39,23 @@ export const useInvestigateInResolverContextItem = ({
}: InvestigateInResolverProps) => {
const dispatch = useDispatch();
const isDisabled = useMemo(() => !isInvestigateInResolverActionEnabled(ecsData), [ecsData]);
const { setGlobalFullScreen } = useGlobalFullScreen();
const { setTimelineFullScreen } = useTimelineFullScreen();
const handleClick = useCallback(() => {
const dataGridIsFullScreen = document.querySelector('.euiDataGrid--fullScreen');
dispatch(updateTimelineGraphEventId({ id: timelineId, graphEventId: ecsData._id }));
if (timelineId === TimelineId.active) {
if (dataGridIsFullScreen) {
setTimelineFullScreen(true);
}
dispatch(setActiveTabTimeline({ id: timelineId, activeTab: TimelineTabs.graph }));
} else {
if (dataGridIsFullScreen) {
setGlobalFullScreen(true);
}
}
onClose();
}, [dispatch, ecsData._id, onClose, timelineId]);
}, [dispatch, ecsData._id, onClose, timelineId, setGlobalFullScreen, setTimelineFullScreen]);
return isDisabled
? []
: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ describe('GraphOverlay', () => {
});
});

test('it has a calculated width that makes room for the Timeline flyout button when isEventViewer is true in full screen mode', async () => {
test('it has a fixed position when isEventViewer is true in full screen mode', async () => {
(useGlobalFullScreen as jest.Mock).mockReturnValue({
globalFullScreen: true, // <-- true when an events viewer is in full screen mode
setGlobalFullScreen: jest.fn(),
Expand All @@ -77,7 +77,7 @@ describe('GraphOverlay', () => {

await waitFor(() => {
const overlayContainer = wrapper.find('[data-test-subj="overlayContainer"]').first();
expect(overlayContainer).toHaveStyleRule('width', 'calc(100% - 36px)');
expect(overlayContainer).toHaveStyleRule('position', 'fixed');
});
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,15 @@ const OverlayContainer = styled.div`
`}
`;

const FullScreenOverlayContainer = styled.div`
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: ${(props) => props.theme.eui.euiZLevel3};
`;

const StyledResolver = styled(Resolver)`
height: 100%;
`;
Expand Down Expand Up @@ -113,16 +122,13 @@ const Navigation = React.memo(NavigationComponent);

const GraphOverlayComponent: React.FC<OwnProps> = ({ isEventViewer, timelineId }) => {
const dispatch = useDispatch();
const onCloseOverlay = useCallback(() => {
dispatch(updateTimelineGraphEventId({ id: timelineId, graphEventId: '' }));
}, [dispatch, timelineId]);
const { globalFullScreen, setGlobalFullScreen } = useGlobalFullScreen();
const { timelineFullScreen, setTimelineFullScreen } = useTimelineFullScreen();

const getTimeline = useMemo(() => timelineSelectors.getTimelineByIdSelector(), []);
const graphEventId = useDeepEqualSelector(
(state) => (getTimeline(state, timelineId) ?? timelineDefaults).graphEventId
);

const { globalFullScreen, setGlobalFullScreen } = useGlobalFullScreen();
const { timelineFullScreen, setTimelineFullScreen } = useTimelineFullScreen();
const getStartSelector = useMemo(() => startSelector(), []);
const getEndSelector = useMemo(() => endSelector(), []);
const getIsLoadingSelector = useMemo(() => isLoadingSelector(), []);
Expand Down Expand Up @@ -154,6 +160,17 @@ const GraphOverlayComponent: React.FC<OwnProps> = ({ isEventViewer, timelineId }
[globalFullScreen, timelineId, timelineFullScreen]
);

const isInTimeline = timelineId === TimelineId.active;
console.log(isInTimeline);
const onCloseOverlay = useCallback(() => {
if (timelineId === TimelineId.active) {
setTimelineFullScreen(false);
} else {
setGlobalFullScreen(false);
}
dispatch(updateTimelineGraphEventId({ id: timelineId, graphEventId: '' }));
}, [dispatch, timelineId, setTimelineFullScreen, setGlobalFullScreen]);

const toggleFullScreen = useCallback(() => {
if (timelineId === TimelineId.active) {
setTimelineFullScreen(!timelineFullScreen);
Expand All @@ -173,41 +190,74 @@ const GraphOverlayComponent: React.FC<OwnProps> = ({ isEventViewer, timelineId }
[]
);
const existingIndexNames = useDeepEqualSelector<string[]>(existingIndexNamesSelector);

return (
<OverlayContainer
data-test-subj="overlayContainer"
$restrictWidth={isEventViewer && fullScreen}
>
<EuiHorizontalRule margin="none" />
<EuiFlexGroup gutterSize="none" justifyContent="spaceBetween">
<EuiFlexItem grow={false}>
<Navigation
fullScreen={fullScreen}
globalFullScreen={globalFullScreen}
onCloseOverlay={onCloseOverlay}
timelineId={timelineId}
timelineFullScreen={timelineFullScreen}
toggleFullScreen={toggleFullScreen}
if (fullScreen && !isInTimeline) {
return (
<FullScreenOverlayContainer data-test-subj="overlayContainer">
<EuiHorizontalRule margin="none" />
<EuiFlexGroup gutterSize="none" justifyContent="spaceBetween">
<EuiFlexItem grow={false}>
<Navigation
fullScreen={fullScreen}
globalFullScreen={globalFullScreen}
onCloseOverlay={onCloseOverlay}
timelineId={timelineId}
timelineFullScreen={timelineFullScreen}
toggleFullScreen={toggleFullScreen}
/>
</EuiFlexItem>
</EuiFlexGroup>
<EuiHorizontalRule margin="none" />
{graphEventId !== undefined ? (
<StyledResolver
databaseDocumentID={graphEventId}
resolverComponentInstanceID={timelineId}
indices={existingIndexNames}
shouldUpdate={shouldUpdate}
filters={{ from, to }}
/>
</EuiFlexItem>
</EuiFlexGroup>
<EuiHorizontalRule margin="none" />
{graphEventId !== undefined ? (
<StyledResolver
databaseDocumentID={graphEventId}
resolverComponentInstanceID={timelineId}
indices={existingIndexNames}
shouldUpdate={shouldUpdate}
filters={{ from, to }}
/>
) : (
<EuiFlexGroup alignItems="center" justifyContent="center" style={{ height: '100%' }}>
<EuiLoadingSpinner size="xl" />
) : (
<EuiFlexGroup alignItems="center" justifyContent="center" style={{ height: '100%' }}>
<EuiLoadingSpinner size="xl" />
</EuiFlexGroup>
)}
</FullScreenOverlayContainer>
);
} else {
return (
<OverlayContainer
data-test-subj="overlayContainer"
$restrictWidth={isEventViewer && isInTimeline}
>
<EuiHorizontalRule margin="none" />
<EuiFlexGroup gutterSize="none" justifyContent="spaceBetween">
<EuiFlexItem grow={false}>
<Navigation
fullScreen={fullScreen}
globalFullScreen={globalFullScreen}
onCloseOverlay={onCloseOverlay}
timelineId={timelineId}
timelineFullScreen={timelineFullScreen}
toggleFullScreen={toggleFullScreen}
/>
</EuiFlexItem>
</EuiFlexGroup>
)}
</OverlayContainer>
);
<EuiHorizontalRule margin="none" />
{graphEventId !== undefined ? (
<StyledResolver
databaseDocumentID={graphEventId}
resolverComponentInstanceID={timelineId}
indices={existingIndexNames}
shouldUpdate={shouldUpdate}
filters={{ from, to }}
/>
) : (
<EuiFlexGroup alignItems="center" justifyContent="center" style={{ height: '100%' }}>
<EuiLoadingSpinner size="xl" />
</EuiFlexGroup>
)}
</OverlayContainer>
);
}
};

export const GraphOverlay = React.memo(GraphOverlayComponent);
123 changes: 72 additions & 51 deletions x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@
import type { AlertConsumers as AlertConsumersTyped } from '@kbn/rule-data-utils';
// @ts-expect-error
import { AlertConsumers as AlertConsumersNonTyped } from '@kbn/rule-data-utils/target_node/alerts_as_data_rbac';
import { EuiEmptyPrompt, EuiLoadingContent, EuiPanel } from '@elastic/eui';
import {
EuiEmptyPrompt,
EuiFlexGroup,
EuiFlexItem,
EuiPanel,
EuiLoadingContent,
} from '@elastic/eui';
import { isEmpty } from 'lodash/fp';
import React, { useEffect, useMemo, useRef, useState } from 'react';
import styled from 'styled-components';
Expand Down Expand Up @@ -80,6 +86,16 @@ const EventsContainerLoading = styled.div.attrs(({ className = '' }) => ({
flex-direction: column;
`;

const FullWidthFlexGroup = styled(EuiFlexGroup)<{ $visible: boolean }>`
overflow: hidden;
margin: 0;
display: ${({ $visible }) => ($visible ? 'flex' : 'none')};
`;

const ScrollableFlexItem = styled(EuiFlexItem)`
overflow: auto;
`;

const SECURITY_ALERTS_CONSUMERS = [AlertConsumers.SIEM];

export interface TGridIntegratedProps {
Expand Down Expand Up @@ -309,56 +325,61 @@ const TGridIntegratedComponent: React.FC<TGridIntegratedProps> = ({
</UpdatedFlexGroup>

{!graphEventId && graphOverlay == null && (
<>
{totalCountMinusDeleted === 0 && loading === false && (
<EuiEmptyPrompt
title={
<h2>
<FormattedMessage
id="xpack.timelines.tGrid.noResultsMatchSearchCriteriaTitle"
defaultMessage="No results match your search criteria"
/>
</h2>
}
titleSize="s"
body={
<p>
<FormattedMessage
id="xpack.timelines.tGrid.noResultsMatchSearchCriteriaDescription"
defaultMessage="Try searching over a longer period of time or modifying your search."
/>
</p>
}
/>
)}
{totalCountMinusDeleted > 0 && (
<StatefulBody
hasAlertsCrud={hasAlertsCrud}
activePage={pageInfo.activePage}
browserFields={browserFields}
filterQuery={filterQuery}
data={nonDeletedEvents}
defaultCellActions={defaultCellActions}
id={id}
isEventViewer={true}
itemsPerPageOptions={itemsPerPageOptions}
loadPage={loadPage}
onRuleChange={onRuleChange}
pageSize={itemsPerPage}
renderCellValue={renderCellValue}
rowRenderers={rowRenderers}
tabType={TimelineTabs.query}
tableView={tableView}
totalItems={totalCountMinusDeleted}
unit={unit}
filterStatus={filterStatus}
leadingControlColumns={leadingControlColumns}
trailingControlColumns={trailingControlColumns}
refetch={refetch}
indexNames={indexNames}
/>
)}
</>
<FullWidthFlexGroup
$visible={!graphEventId && graphOverlay == null}
gutterSize="none"
>
<ScrollableFlexItem grow={1}>
{totalCountMinusDeleted === 0 && loading === false && (
<EuiEmptyPrompt
title={
<h2>
<FormattedMessage
id="xpack.timelines.tGrid.noResultsMatchSearchCriteriaTitle"
defaultMessage="No results match your search criteria"
/>
</h2>
}
titleSize="s"
body={
<p>
<FormattedMessage
id="xpack.timelines.tGrid.noResultsMatchSearchCriteriaDescription"
defaultMessage="Try searching over a longer period of time or modifying your search."
/>
</p>
}
/>
)}
{totalCountMinusDeleted > 0 && (
<StatefulBody
hasAlertsCrud={hasAlertsCrud}
activePage={pageInfo.activePage}
browserFields={browserFields}
filterQuery={filterQuery}
data={nonDeletedEvents}
defaultCellActions={defaultCellActions}
id={id}
isEventViewer={true}
itemsPerPageOptions={itemsPerPageOptions}
loadPage={loadPage}
onRuleChange={onRuleChange}
pageSize={itemsPerPage}
renderCellValue={renderCellValue}
rowRenderers={rowRenderers}
tabType={TimelineTabs.query}
tableView={tableView}
totalItems={totalCountMinusDeleted}
unit={unit}
filterStatus={filterStatus}
leadingControlColumns={leadingControlColumns}
trailingControlColumns={trailingControlColumns}
refetch={refetch}
indexNames={indexNames}
/>
)}
</ScrollableFlexItem>
</FullWidthFlexGroup>
)}
</EventsContainerLoading>
)}
Expand Down

0 comments on commit e610891

Please sign in to comment.