From 82ccb8d6d38e045992ec4db38399d6ab02ba72ad Mon Sep 17 00:00:00 2001 From: Umberto Pepato Date: Thu, 4 Apr 2024 13:06:40 +0200 Subject: [PATCH] [RAM] Enable custom alerts table cell popovers (#176804) ## Summary Adds the `renderCellPopover` and `getRenderCellPopover` configuration options to the alerts table in order to allow customizing the cell popovers. --- .../sections/alerts_table/alerts_table.tsx | 103 +++++++++++++----- .../alerts_table/alerts_table_state.tsx | 6 +- .../triggers_actions_ui/public/types.ts | 13 ++- 3 files changed, 93 insertions(+), 29 deletions(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.tsx index dcc3bafeb92ba..14fc3a3755980 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.tsx @@ -24,10 +24,12 @@ import { EuiDataGridRefProps, EuiFlexGroup, EuiDataGridProps, + EuiDataGridCellPopoverElementProps, EuiCodeBlock, EuiText, EuiIcon, EuiSpacer, + EuiFlexItem, } from '@elastic/eui'; import { useQueryClient } from '@tanstack/react-query'; import styled from '@emotion/styled'; @@ -134,6 +136,44 @@ const CustomGridBody = memo( } ); +// Here we force the error callout to be the same height as the cell content +// so that the error detail gets hidden in the overflow area and only shown in +// the cell popover +const errorCalloutStyles = css` + height: 1lh; +`; + +/** + * An error callout that displays the error stack in a code block + */ +const ViewError = ({ error }: { error: Error }) => ( + <> + + + + + + + + + + + + + + {error.stack} + +); + const AlertsTable: React.FunctionComponent = (props: AlertsTableProps) => { const { visibleColumns, @@ -381,12 +421,10 @@ const AlertsTable: React.FunctionComponent = (props: AlertsTab const renderCellValue = useCallback( () => - props.alertsTableConfiguration?.getRenderCellValue - ? props.alertsTableConfiguration?.getRenderCellValue({ - setFlyoutAlert: handleFlyoutAlert, - context: renderCellContext, - }) - : basicRenderCellValue, + props.alertsTableConfiguration?.getRenderCellValue?.({ + setFlyoutAlert: handleFlyoutAlert, + context: renderCellContext, + }) ?? basicRenderCellValue, [handleFlyoutAlert, props.alertsTableConfiguration, renderCellContext] )(); @@ -427,27 +465,7 @@ const AlertsTable: React.FunctionComponent = (props: AlertsTab } return null; } catch (e) { - return ( - <> - - - - - - - - {e.stack} - - ); + return ; } }, [ @@ -466,6 +484,36 @@ const AlertsTable: React.FunctionComponent = (props: AlertsTab ] ); + const renderCellPopover = useMemo( + () => + props.alertsTableConfiguration?.getRenderCellPopover?.({ + context: renderCellContext, + }) ?? props.renderCellPopover, + [props.alertsTableConfiguration, props.renderCellPopover, renderCellContext] + ); + + const handleRenderCellPopover = useMemo( + () => + renderCellPopover + ? (_props: EuiDataGridCellPopoverElementProps) => { + try { + const idx = _props.rowIndex - pagination.pageSize * pagination.pageIndex; + const alert = alerts[idx]; + if (alert) { + return renderCellPopover({ + ..._props, + alert, + }); + } + return null; + } catch (e) { + return ; + } + } + : undefined, + [alerts, pagination.pageIndex, pagination.pageSize, renderCellPopover] + ); + const dataGridPagination = useMemo( () => ({ ...pagination, @@ -593,6 +641,7 @@ const AlertsTable: React.FunctionComponent = (props: AlertsTab onColumnResize={onColumnResize} ref={dataGridRef} renderCustomGridBody={props.dynamicRowHeight ? renderCustomGridBody : undefined} + renderCellPopover={handleRenderCellPopover} /> )} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table_state.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table_state.tsx index 2c0e7873254bf..99362eb2e96ee 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table_state.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table_state.tsx @@ -93,7 +93,8 @@ export type AlertsTableStateProps = { */ dynamicRowHeight?: boolean; lastReloadRequestTime?: number; -} & Partial; + renderCellPopover?: AlertsTableProps['renderCellPopover']; +} & Omit, 'renderCellPopover'>; export interface AlertsTableStorage { columns: EuiDataGridColumn[]; @@ -185,6 +186,7 @@ const AlertsTableStateWithQueryProvider = ({ leadingControlColumns, rowHeightsOptions, renderCellValue, + renderCellPopover, columns: propColumns, gridStyle, browserFields: propBrowserFields, @@ -449,6 +451,7 @@ const AlertsTableStateWithQueryProvider = ({ query, rowHeightsOptions, renderCellValue, + renderCellPopover, gridStyle, controls: persistentControls, showInspectButton, @@ -477,6 +480,7 @@ const AlertsTableStateWithQueryProvider = ({ query, rowHeightsOptions, renderCellValue, + renderCellPopover, gridStyle, persistentControls, showInspectButton, diff --git a/x-pack/plugins/triggers_actions_ui/public/types.ts b/x-pack/plugins/triggers_actions_ui/public/types.ts index 7533746c87236..467d9480a248e 100644 --- a/x-pack/plugins/triggers_actions_ui/public/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/types.ts @@ -24,6 +24,7 @@ import type { EuiDataGridToolBarVisibilityOptions, EuiSuperSelectOption, EuiDataGridOnColumnResizeHandler, + EuiDataGridCellPopoverElementProps, } from '@elastic/eui'; import type { RuleCreationValidConsumer, ValidFeatureId } from '@kbn/rule-data-utils'; import { EuiDataGridColumn, EuiDataGridControlColumn, EuiDataGridSorting } from '@elastic/eui'; @@ -587,6 +588,7 @@ export type AlertsTableProps = { */ dynamicRowHeight?: boolean; featureIds?: ValidFeatureId[]; + renderCellPopover?: ReturnType; } & Partial>; export type SetFlyoutAlert = (alertId: string) => void; @@ -605,7 +607,15 @@ export type GetRenderCellValue = ({ context?: T; }) => ( props: EuiDataGridCellValueElementProps & { data: TimelineNonEcsData[] } -) => React.ReactNode | JSX.Element | null | string; +) => React.ReactNode | JSX.Element; + +export type GetRenderCellPopover = ({ + context, +}: { + context?: T; +}) => ( + props: EuiDataGridCellPopoverElementProps & { alert: Alert } +) => React.ReactNode | JSX.Element; export type PreFetchPageContext = ({ alerts, @@ -739,6 +749,7 @@ export interface AlertsTableConfigurationRegistry { }; sort?: SortCombinations[]; getRenderCellValue?: GetRenderCellValue; + getRenderCellPopover?: GetRenderCellPopover; useActionsColumn?: UseActionsColumnRegistry; useBulkActions?: UseBulkActionsRegistry; useCellActions?: UseCellActions;