33 * SPDX-License-Identifier: Apache-2.0
44 */
55
6- import React , { useCallback , useEffect , useMemo , useRef , useState } from 'react' ;
6+ import React , { useCallback , useEffect , useMemo , useState } from 'react' ;
77import { EuiDataGrid , EuiDataGridCellValueElementProps , EuiDataGridColumn } from '@elastic/eui' ;
88import { VisColumn , VisFieldType } from '../types' ;
99import { defaultTableChartStyles , CellTypeConfig , TableChartStyle } from './table_vis_config' ;
@@ -21,15 +21,108 @@ interface TableVisProps {
2121 styleOptions ?: TableChartStyle ;
2222 pageSizeOptions ?: number [ ] ;
2323 showStyleSelector ?: boolean ;
24+ onStyleChange ?: ( updatedStyle : Partial < TableChartStyle > ) => void ;
25+ disableActions ?: boolean ;
2426}
2527
2628export const TableVis = React . memo (
27- ( { rows, columns, styleOptions, pageSizeOptions, showStyleSelector } : TableVisProps ) => {
28- const sortedColumns = useMemo ( ( ) => [ ...columns ] . sort ( ( a , b ) => a . id - b . id ) , [ columns ] ) ;
29+ ( {
30+ rows,
31+ columns,
32+ styleOptions,
33+ pageSizeOptions,
34+ showStyleSelector,
35+ onStyleChange,
36+ disableActions,
37+ } : TableVisProps ) => {
38+ const sortedColumns = useMemo ( ( ) => {
39+ const baseColumns = [ ...columns ] . sort ( ( a , b ) => a . id - b . id ) ;
40+
41+ // If user has a saved column order, use it
42+ if ( styleOptions ?. visibleColumns && styleOptions . visibleColumns . length > 0 ) {
43+ const userOrder = styleOptions . visibleColumns ;
44+ const orderedColumns : VisColumn [ ] = [ ] ;
45+
46+ // First, add columns in user-specified order
47+ userOrder . forEach ( ( columnName ) => {
48+ const foundColumn = baseColumns . find ( ( col ) => col . name === columnName ) ;
49+ if ( foundColumn ) {
50+ orderedColumns . push ( foundColumn ) ;
51+ }
52+ } ) ;
53+
54+ // Then add any new columns that weren't in the saved order
55+ baseColumns . forEach ( ( col ) => {
56+ if ( ! userOrder . includes ( col . name ) ) {
57+ orderedColumns . push ( col ) ;
58+ }
59+ } ) ;
60+
61+ return orderedColumns ;
62+ }
63+
64+ return baseColumns ;
65+ } , [ columns , styleOptions ?. visibleColumns ] ) ;
66+
2967 const [ visibleColumns , setVisibleColumns ] = useState ( ( ) =>
3068 sortedColumns . map ( ( { column } ) => column )
3169 ) ;
3270
71+ // Update visibleColumns when sortedColumns changes, preserving user's visibility choices
72+ useEffect ( ( ) => {
73+ // Apply hiddenColumns from saved configuration if available
74+ const hiddenColumns = styleOptions ?. hiddenColumns || [ ] ;
75+ const visibleColumnsFromConfig = sortedColumns . filter (
76+ ( col ) => ! hiddenColumns . includes ( col . name )
77+ ) ;
78+
79+ setVisibleColumns ( visibleColumnsFromConfig . map ( ( col ) => col . column ) ) ;
80+ } , [ sortedColumns , styleOptions ?. hiddenColumns ] ) ;
81+
82+ // Handle user column order changes - directly save any reorder/hide operations
83+ const handleColumnVisibilityChange = useCallback (
84+ ( updatedVisibleColumns : string [ ] ) => {
85+ const previousVisibleColumns = visibleColumns ;
86+ setVisibleColumns ( updatedVisibleColumns ) ;
87+
88+ // Always save user changes when onStyleChange is available
89+ if ( onStyleChange ) {
90+ const allColumns = sortedColumns . map ( ( col ) => col . column ) ;
91+
92+ // Check if this is a reordering or visibility change
93+ const isReordering =
94+ updatedVisibleColumns . length === previousVisibleColumns . length &&
95+ updatedVisibleColumns . every ( ( col ) => previousVisibleColumns . includes ( col ) ) ;
96+
97+ // Calculate hidden columns
98+ const newHiddenColumns = allColumns . filter ( ( col ) => ! updatedVisibleColumns . includes ( col ) ) ;
99+
100+ if ( isReordering ) {
101+ // This is a reordering operation - update column order
102+ const finalUserOrder : string [ ] = [ ] ;
103+
104+ finalUserOrder . push ( ...updatedVisibleColumns ) ;
105+
106+ onStyleChange ( {
107+ visibleColumns : finalUserOrder
108+ . map ( ( id ) => sortedColumns . find ( ( col ) => col . column === id ) ?. name ?? '' )
109+ . filter ( Boolean ) ,
110+ } ) ;
111+ } else {
112+ // This is a visibility change - save hidden columns and update order if needed
113+ const updates : Partial < TableChartStyle > = {
114+ hiddenColumns : newHiddenColumns
115+ . map ( ( id ) => sortedColumns . find ( ( col ) => col . column === id ) ?. name ?? '' )
116+ . filter ( Boolean ) ,
117+ } ;
118+
119+ onStyleChange ( updates ) ;
120+ }
121+ }
122+ } ,
123+ [ onStyleChange , visibleColumns , sortedColumns ]
124+ ) ;
125+
33126 const pageSize = styleOptions ?. pageSize ?? defaultTableChartStyles . pageSize ;
34127 const [ pagination , setPagination ] = useState ( { pageIndex : 0 , pageSize } ) ;
35128 const [ filters , setFilters ] = useState < Record < string , FilterConfig > > ( { } ) ;
@@ -69,6 +162,7 @@ export const TableVis = React.memo(
69162 return sortedColumns . map ( ( col ) => ( {
70163 id : col . column ,
71164 displayAsText : col . name ,
165+ actions : disableActions ? false : undefined ,
72166 display : (
73167 < TableColumnHeader
74168 col = { col }
@@ -88,6 +182,7 @@ export const TableVis = React.memo(
88182 filters ,
89183 columnUniques ,
90184 setFilters ,
185+ disableActions ,
91186 ] ) ;
92187
93188 const onChangeItemsPerPage = useCallback ( ( newPageSize : number ) => {
@@ -240,7 +335,7 @@ export const TableVis = React.memo(
240335 className = "tableVis__dataGrid"
241336 aria-label = "Table visualization"
242337 columns = { dataGridColumns }
243- columnVisibility = { { visibleColumns, setVisibleColumns } }
338+ columnVisibility = { { visibleColumns, setVisibleColumns : handleColumnVisibilityChange } }
244339 rowCount = { filteredRows . length }
245340 pagination = { {
246341 ...pagination ,
@@ -252,7 +347,8 @@ export const TableVis = React.memo(
252347 renderFooterCellValue = { styleOptions ?. showFooter ? renderFooterCellValue : undefined }
253348 toolbarVisibility = { {
254349 showFullScreenSelector : false ,
255- showStyleSelector : showStyleSelector ?? true ,
350+ showStyleSelector : disableActions ? false : showStyleSelector ?? true ,
351+ showColumnSelector : disableActions ? false : true ,
256352 } }
257353 gridStyle = { { rowHover : 'highlight' } }
258354 leadingControlColumns = { [ ] }
0 commit comments