[Security Solution][Bug] fix popover in t-grid (#145025)

This PR contains fixes for the following issues:

#### # 1 Popover overlaps flyout
- https://github.com/elastic/kibana/issues/139280
- https://github.com/elastic/kibana/issues/128235
#### # 2 Popover persists after clicking filter out
- https://github.com/elastic/kibana/issues/115341
#### # 3 Popover persists after clicking a button outside of popover
- https://github.com/elastic/kibana/issues/118844

## Background
Previously, a cell's popover remains open after clicking an action. In
many cases we want the popover to close upon clicking on a cell action.
EUI team addressed this by adding a `closeCellPopover` to a `ref` API.
- https://github.com/elastic/eui/pull/5590

In T-grid, there are 2 types of cell actions: 
- Default cell actions such as filter in, filter out, add to timeline
and copy. `closeCellPopover` is not used.
- Formatted fields that have more information in the form of flyouts
(host name, user name, ip, etc.)
`closeCellPopover` prop is passed but currently not working as expected.

This PR contains fixes for: 
- Fixing `closeCellPopover` in T-grid body for formatted fields - fixes
# 1
- Adding `closeCellPopover` props in default cell actions - fixes # 2
and # 3

## # 1 - `closeCellPopover` in T-grid 

`dataGridRef.current?.closeCellPopover` was added and intended to close
any open popovers when a cell action is clicked. However, because it is
a mutable object, it is not being monitored in `columnsWithCellActions`.
When the page is initially loaded, `dataGridRef.current` remain as null
and it does not update until the page re-renders and `dataGridRef`
becomes non-null.
- After: popover closes properly


https://user-images.githubusercontent.com/18648970/201202326-ec657f78-c425-46a6-9356-f6e9ef1ab798.mov


## # 2 & # 3 Add `closeCellPopover` to default cell actions

- After: upon opening the expansion popover, clicking any options and
the popover will disappear


https://user-images.githubusercontent.com/18648970/201417542-063c514b-5474-4676-a747-a9401627c5e8.mov

- After: upon opening the expansion popover, clicking any options
outside and the popover will disappear


https://user-images.githubusercontent.com/18648970/201417678-7cf0fefa-f4a7-4a70-9a10-76b248323639.mov

Note for UX: although QA only flagged `filter out` and `add to
timeline`, for consistency's sake, the expansion popover will disappear
after clicking any of the cell actions, which includes `filter in` and
`copy`.
This commit is contained in:
christineweng 2022-11-15 18:02:55 -06:00 committed by GitHub
parent 256e1f8bd5
commit 05d1ff852c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 26 additions and 1 deletions

View file

@ -25,9 +25,11 @@ import { addProvider } from '../../../timelines/store/timeline/actions';
export const getAddToTimelineCellAction = ({
data,
pageSize,
closeCellPopover,
}: {
data?: TimelineNonEcsData[][];
pageSize: number;
closeCellPopover?: () => void;
}) =>
data && data.length > 0
? function AddToTimeline({ rowIndex, columnId, Component }: EuiDataGridColumnCellActionProps) {
@ -97,6 +99,9 @@ export const getAddToTimelineCellAction = ({
providers: dataProvider,
})
);
if (closeCellPopover) {
closeCellPopover();
}
}, [dataProvider, dispatch]);
const addToTimelineProps = useMemo(() => {

View file

@ -16,9 +16,11 @@ import { EmptyComponent, useKibanaServices } from './helpers';
export const getCopyCellAction = ({
data,
pageSize,
closeCellPopover,
}: {
data?: TimelineNonEcsData[][];
pageSize: number;
closeCellPopover?: () => void;
}) =>
data && data.length > 0
? function CopyButton({ rowIndex, columnId, Component }: EuiDataGridColumnCellActionProps) {
@ -45,6 +47,7 @@ export const getCopyCellAction = ({
ownFocus: false,
showTooltip: false,
value,
onClick: closeCellPopover,
};
}, [Component, columnId, value]);

View file

@ -22,6 +22,7 @@ interface Props {
scopeId: string;
value: string[] | undefined;
onFilterAdded?: () => void;
closeCellPopover?: () => void;
}
const StyledFlexGroup = styled(EuiFlexGroup)`
@ -40,6 +41,7 @@ const ExpandedCellValueActionsComponent: React.FC<Props> = ({
onFilterAdded,
scopeId,
value,
closeCellPopover,
}) => {
const {
timelines,
@ -99,6 +101,7 @@ const ExpandedCellValueActionsComponent: React.FC<Props> = ({
size: 's',
showTooltip: false,
value,
onClick: closeCellPopover,
})}
</EuiFlexItem>
<EuiFlexItem>
@ -111,6 +114,7 @@ const ExpandedCellValueActionsComponent: React.FC<Props> = ({
size: 's',
showTooltip: false,
value,
onClick: closeCellPopover,
})}
</EuiFlexItem>
</StyledFlexGroup>

View file

@ -16,9 +16,11 @@ import { EmptyComponent, onFilterAdded, useKibanaServices } from './helpers';
export const getFilterForCellAction = ({
data,
pageSize,
closeCellPopover,
}: {
data?: TimelineNonEcsData[][];
pageSize: number;
closeCellPopover?: () => void;
}) =>
data && data.length > 0
? function FilterFor({ rowIndex, columnId, Component }: EuiDataGridColumnCellActionProps) {
@ -47,6 +49,7 @@ export const getFilterForCellAction = ({
ownFocus: false,
showTooltip: false,
value,
onClick: closeCellPopover,
};
}, [Component, columnId, filterManager, value]);

View file

@ -15,9 +15,11 @@ import { EmptyComponent, onFilterAdded, useKibanaServices } from './helpers';
export const getFilterOutCellAction = ({
data,
pageSize,
closeCellPopover,
}: {
data?: TimelineNonEcsData[][];
pageSize: number;
closeCellPopover?: () => void;
}) =>
data && data.length > 0
? function FilterOut({ rowIndex, columnId, Component }: EuiDataGridColumnCellActionProps) {
@ -47,6 +49,7 @@ export const getFilterOutCellAction = ({
ownFocus: false,
showTooltip: false,
value,
onClick: closeCellPopover,
};
}, [Component, columnId, filterManager, value]);

View file

@ -36,6 +36,7 @@ export const DefaultCellRenderer: React.FC<CellValueElementProps> = ({
setCellProps,
scopeId,
truncate,
closeCellPopover,
}) => {
const asPlainText = useMemo(() => {
return getLinkColumnDefinition(header.id, header.type, undefined) !== undefined && !isTimeline;
@ -72,6 +73,7 @@ export const DefaultCellRenderer: React.FC<CellValueElementProps> = ({
globalFilters={globalFilters}
scopeId={scopeId}
value={values}
closeCellPopover={closeCellPopover}
/>
)}
</>

View file

@ -30,4 +30,5 @@ export type CellValueElementProps = EuiDataGridCellValueElementProps & {
scopeId: string;
truncate?: boolean;
key?: string;
closeCellPopover?: () => void;
};

View file

@ -732,6 +732,7 @@ export const BodyComponent = React.memo<StatefulBodyProps>(
setEventsDeleted,
hasAlertsCrudPermissions,
]);
const closeCellPopoverAction = dataGridRef.current?.closeCellPopover;
const columnsWithCellActions: EuiDataGridColumn[] = useMemo(
() =>
columnHeaders.map((header) => {
@ -743,7 +744,7 @@ export const BodyComponent = React.memo<StatefulBodyProps>(
header: columnHeaders.find((h) => h.id === header.id),
pageSize,
scopeId: id,
closeCellPopover: dataGridRef.current?.closeCellPopover,
closeCellPopover: closeCellPopoverAction,
});
return {
...header,
@ -782,6 +783,7 @@ export const BodyComponent = React.memo<StatefulBodyProps>(
dispatch,
id,
pageSize,
closeCellPopoverAction,
]
);
@ -833,6 +835,7 @@ export const BodyComponent = React.memo<StatefulBodyProps>(
setCellProps,
scopeId: id,
truncate: isDetails ? false : true,
closeCellPopover: closeCellPopoverAction,
}) as React.ReactElement;
};
return Cell;
@ -846,6 +849,7 @@ export const BodyComponent = React.memo<StatefulBodyProps>(
renderCellValue,
rowRenderers,
theme,
closeCellPopoverAction,
]);
const onChangeItemsPerPage = useCallback(