import React , { useCallback , useEffect , useMemo , useState } from 'react' ; import { EuiDataGridSorting , EuiDataGridColumn } from '@elastic/eui' ; import { ES_CLIENT_TOTAL_HITS_RELATION } from '../../../../common/types/es_client' ; import { ChartData } from '../../../../common/types/field_histograms' ; import { INDEX_STATUS } from '../../data_frame_analytics/common' ; import { ColumnChart } from './column_chart' ; import { COLUMN_CHART_DEFAULT_VISIBILITY_ROWS_THRESHOLED , INIT_MAX_COLUMNS } from './common' ; import { ChartsVisible , ColumnId , DataGridItem , IndexPagination , OnChangeItemsPerPage , OnChangePage , OnSort , RowCountRelation , UseDataGridReturnType , } from './types' ; export const useDataGrid = ( columns , defaultPageSize = 5 , defaultVisibleColumnsCount = INIT_MAX_COLUMNS , defaultVisibleColumnsFilter ? ) : UseDataGridReturnType => { const defaultPagination = { pageIndex : 0 , pageSize : defaultPageSize } ; const [ ccsWarning , setCcsWarning ] = useState ( false ) ; const [ noDataMessage , setNoDataMessage ] = useState ( '' ) ; const [ errorMessage , setErrorMessage ] = useState ( '' ) ; const [ status , setStatus ] = useState ( INDEX_STATUS . UNUSED ) ; const [ rowCount , setRowCount ] = useState ( 0 ) ; const [ rowCountRelation , setRowCountRelation ] = useState < RowCountRelation > ( undefined ) ; const [ columnCharts , setColumnCharts ] = useState < ChartData [ ] > ( [ ] ) ; const [ tableItems , setTableItems ] = useState < DataGridItem [ ] > ( [ ] ) ; const [ pagination , setPagination ] = useState ( defaultPagination ) ; const [ sortingColumns , setSortingColumns ] = useState < EuiDataGridSorting [ 'columns' ] > ( [ ] ) ; const [ chartsVisible , setChartsVisible ] = useState < ChartsVisible > ( undefined ) ; const toggleChartVisibility = ( ) => { if ( chartsVisible !== undefined ) { setChartsVisible ( ! chartsVisible ) ; } } ; const onChangeItemsPerPage = useCallback ( ( pageSize ) => { setPagination ( ( p ) => { const pageIndex = Math . floor ( ( p . pageSize * p . pageIndex ) / pageSize ) ; return { pageIndex , pageSize } ; } ) ; } , [ ] ) ; const onChangePage = useCallback ( ( pageIndex ) => setPagination ( ( p ) => ( { ... p , pageIndex } ) ) , [ ] ) ; const resetPagination = ( ) => setPagination ( defaultPagination ) ; const [ visibleColumns , setVisibleColumns ] = useState < ColumnId [ ] > ( [ ] ) ; const columnIds = columns . map ( ( c ) => c . id ) ; const filteredColumnIds = defaultVisibleColumnsFilter !== undefined ? columnIds . filter ( defaultVisibleColumnsFilter ) : columnIds ; const defaultVisibleColumns = filteredColumnIds . splice ( 0 , defaultVisibleColumnsCount ) ; useEffect ( ( ) => { setVisibleColumns ( defaultVisibleColumns ) ; } , [ defaultVisibleColumns . join ( ) ] ) ; const [ invalidSortingColumnns , setInvalidSortingColumnns ] = useState < string [ ] > ( [ ] ) ; const onSort = useCallback ( ( sc ) => { const updatedInvalidSortingColumnns = sc . reduce < string [ ] > ( ( arr , current ) => { const columnType = columns . find ( ( dgc ) => dgc . id === current . id ) ; if ( columnType ?. schema === 'json' ) { arr . push ( current . id ) ; } return arr ; } , [ ] ) ; setInvalidSortingColumnns ( updatedInvalidSortingColumnns ) ; if ( updatedInvalidSortingColumnns . length === 0 ) { setSortingColumns ( sc ) ; } } , [ columns ] ) ; const columnsWithCharts = useMemo ( ( ) => { const updatedColumns = columns . map ( ( c , index ) => { const chartData = columnCharts . find ( ( cd ) => cd . id === c . id ) ; return { ... c , display : chartData !== undefined && chartsVisible === true ? ( < ColumnChart chartData = { chartData } columnType = { c } dataTestSubj = { `mlDataGridChart-${ c . id }` } / > ) : undefined , } ; } ) ; return updatedColumns . sort ( ( a , b ) => { if ( visibleColumns . indexOf ( a . id ) === - 1 && visibleColumns . indexOf ( b . id ) > - 1 ) { return 1 ; } if ( visibleColumns . indexOf ( b . id ) === - 1 && visibleColumns . indexOf ( a . id ) > - 1 ) { return - 1 ; } if ( visibleColumns . indexOf ( a . id ) === - 1 && visibleColumns . indexOf ( b . id ) === - 1 ) { return a . id . localeCompare ( b . id ) ; } return visibleColumns . indexOf ( a . id ) - visibleColumns . indexOf ( b . id ) ; } ) ; } , [ columns , columnCharts , chartsVisible , JSON . stringify ( visibleColumns ) ] ) ; useEffect ( ( ) => { if ( chartsVisible === undefined && rowCount > 0 && rowCountRelation !== undefined ) { setChartsVisible ( rowCount <= COLUMN_CHART_DEFAULT_VISIBILITY_ROWS_THRESHOLED && rowCountRelation !== ES_CLIENT_TOTAL_HITS_RELATION . GTE ) ; } } , [ chartsVisible , rowCount , rowCountRelation ] ) ; return { ccsWarning , chartsVisible , chartsButtonVisible : true , columnsWithCharts , errorMessage , invalidSortingColumnns , noDataMessage , onChangeItemsPerPage , onChangePage , onSort , pagination , resetPagination , rowCount , rowCountRelation , setColumnCharts , setCcsWarning , setErrorMessage , setNoDataMessage , setPagination , setRowCount , setRowCountRelation , setSortingColumns , setStatus , setTableItems , setVisibleColumns , sortingColumns , status , tableItems , toggleChartVisibility , visibleColumns , } ; } ;