@@ -10,16 +10,31 @@ import type {
1010 EuiDataGridRowHeightsOptions ,
1111 EuiDataGridSorting ,
1212} from '@elastic/eui' ;
13- import { EuiDataGrid , useEuiTheme } from '@elastic/eui' ;
13+ import {
14+ EuiAvatar ,
15+ EuiButtonIcon ,
16+ EuiDataGrid ,
17+ EuiFlexGroup ,
18+ EuiToolTip ,
19+ useEuiTheme ,
20+ } from '@elastic/eui' ;
1421import { i18n } from '@kbn/i18n' ;
1522import type { SampleDocument } from '@kbn/streams-schema' ;
1623import React , { useMemo , useState , useCallback } from 'react' ;
1724import { css } from '@emotion/css' ;
1825import { recalcColumnWidths } from '../stream_detail_enrichment/utils' ;
19- import type { SimulationContext } from '../stream_detail_enrichment/state_management/simulation_state_machine' ;
26+ import type {
27+ SampleDocumentWithUIAttributes ,
28+ SimulationContext ,
29+ } from '../stream_detail_enrichment/state_management/simulation_state_machine' ;
30+ import { DATA_SOURCES_I18N } from '../stream_detail_enrichment/data_sources_flyout/translations' ;
31+ import { useDataSourceSelectorById } from '../stream_detail_enrichment/state_management/data_source_state_machine' ;
32+ import type { EnrichmentDataSourceWithUIAttributes } from '../stream_detail_enrichment/types' ;
2033
2134const emptyCell = < > </ > ;
2235
36+ export const MemoPreviewTable = React . memo ( PreviewTable ) ;
37+
2338export function PreviewTable ( {
2439 documents,
2540 displayColumns,
@@ -32,7 +47,9 @@ export function PreviewTable({
3247 setVisibleColumns,
3348 columnOrderHint = [ ] ,
3449 selectedRowIndex,
35- leadingControlColumns,
50+ showRowSourceAvatars = false ,
51+ originalSamples,
52+ onRowSelected,
3653} : {
3754 documents : SampleDocument [ ] ;
3855 displayColumns ?: string [ ] ;
@@ -45,7 +62,9 @@ export function PreviewTable({
4562 sorting ?: SimulationContext [ 'previewColumnsSorting' ] ;
4663 setSorting ?: ( sorting : SimulationContext [ 'previewColumnsSorting' ] ) => void ;
4764 selectedRowIndex ?: number ;
48- leadingControlColumns ?: EuiDataGridControlColumn [ ] ;
65+ showRowSourceAvatars ?: boolean ;
66+ originalSamples ?: SampleDocumentWithUIAttributes [ ] ;
67+ onRowSelected ?: ( rowIndex : number ) => void ;
4968} ) {
5069 const { euiTheme : theme } = useEuiTheme ( ) ;
5170 // Determine canonical column order
@@ -117,6 +136,43 @@ export function PreviewTable({
117136
118137 const [ columnWidths , setColumnWidths ] = useState < Record < string , number | undefined > > ( { } ) ;
119138
139+ const leadingControlColumns : EuiDataGridControlColumn [ ] = useMemo (
140+ ( ) => [
141+ {
142+ id : 'selection' ,
143+ width : showRowSourceAvatars ? 72 : 36 ,
144+ headerCellRender : ( ) => null ,
145+ rowCellRender : ( { rowIndex } ) => {
146+ const originalSample = originalSamples ?. [ rowIndex ] ;
147+ return (
148+ < EuiFlexGroup gutterSize = "s" >
149+ < EuiButtonIcon
150+ onClick = { ( ) => {
151+ if ( onRowSelected ) {
152+ onRowSelected ( rowIndex ) ;
153+ }
154+ } }
155+ aria-label = { i18n . translate (
156+ 'xpack.streams.resultPanel.euiDataGrid.preview.selectRowAriaLabel' ,
157+ {
158+ defaultMessage : 'Select row {rowIndex}' ,
159+ values : { rowIndex : rowIndex + 1 } ,
160+ }
161+ ) }
162+ iconType = { selectedRowIndex === rowIndex ? 'minimize' : 'expand' }
163+ color = { selectedRowIndex === rowIndex ? 'primary' : 'text' }
164+ />
165+ { showRowSourceAvatars && originalSample && (
166+ < RowSourceAvatar originalSample = { originalSample } />
167+ ) }
168+ </ EuiFlexGroup >
169+ ) ;
170+ } ,
171+ } ,
172+ ] ,
173+ [ onRowSelected , showRowSourceAvatars , selectedRowIndex , originalSamples ]
174+ ) ;
175+
120176 // Derive visibleColumns from canonical order
121177 const visibleColumns = useMemo ( ( ) => {
122178 if ( displayColumns ) {
@@ -213,3 +269,36 @@ export function PreviewTable({
213269 />
214270 ) ;
215271}
272+
273+ function dataSourceTypeToI18nKey ( type : EnrichmentDataSourceWithUIAttributes [ 'type' ] ) {
274+ switch ( type ) {
275+ case 'random-samples' :
276+ return 'randomSamples' ;
277+ case 'kql-samples' :
278+ return 'kqlDataSource' ;
279+ case 'custom-samples' :
280+ return 'customSamples' ;
281+ }
282+ }
283+
284+ function RowSourceAvatar ( { originalSample } : { originalSample : SampleDocumentWithUIAttributes } ) {
285+ const dataSourceContext = useDataSourceSelectorById (
286+ originalSample . dataSourceId ,
287+ ( snapshot ) => snapshot ?. context
288+ ) ;
289+ if ( ! dataSourceContext ) {
290+ // If the data source context is not available, we cannot render the avatar
291+ return null ;
292+ }
293+ const {
294+ uiAttributes : { color } ,
295+ dataSource : { type : dataSourceType , name : rawDataSourceName } ,
296+ } = dataSourceContext ;
297+ const name =
298+ rawDataSourceName || DATA_SOURCES_I18N [ dataSourceTypeToI18nKey ( dataSourceType ) ] . placeholderName ;
299+ return (
300+ < EuiToolTip content = { name } >
301+ < EuiAvatar size = "s" color = { color } initialsLength = { 1 } name = { name } />
302+ </ EuiToolTip >
303+ ) ;
304+ }
0 commit comments